# NAME SEO::Inspector - Run SEO checks on HTML or URLs # SYNOPSIS use SEO::Inspector; my $inspector = SEO::Inspector->new(url => 'https://example.com'); # Run plugins my $html = '......'; my $plugin_results = $inspector->check_html($html); # Run built-in checks my $builtin_results = $inspector->run_all($html); # Check a single URL and get all results my $all_results = $inspector->check_url('https://example.com'); # DESCRIPTION SEO::Inspector provides: - Built-in SEO checks: title, meta description, canonical link, robots meta, viewport, H1 presence, word count, image alt text - Plugin system: dynamically load modules under SEO::Inspector::Plugin namespace - Methods to check HTML strings or fetch and analyze a URL # PLUGIN SYSTEM In addition to the built-in SEO checks, `SEO::Inspector` supports a flexible plugin system. Plugins allow you to extend the checker with new rules or specialized analysis without modifying the core module. ## How Plugins Are Found Plugins are loaded dynamically from the `SEO::Inspector::Plugin` namespace. For example, a module called: package SEO::Inspector::Plugin::MyCheck; will be detected and loaded automatically if it is available in `@INC`. You can also tell the constructor to search additional directories by passing the `plugin_dirs` argument: my $inspector = SEO::Inspector->new( plugin_dirs => ['t/lib', '/path/to/custom/plugins'], ); Each directory must contain files under a subpath corresponding to the namespace, for example: /path/to/custom/plugins/SEO/Inspector/Plugin/Foo.pm ## Plugin Interface A plugin must provide at least two methods: - `new` Constructor, called with no arguments. - `run($html)` Given a string of raw HTML, return a hashref describing the result of the check. The hashref should have at least these keys: { name => 'My Check', status => 'ok' | 'warn' | 'error', notes => 'human-readable message', } ## Running Plugins You can run all loaded plugins against a piece of HTML with: my $results = $inspector->check_html($html); This returns a hashref keyed by plugin name (lowercased), each value being the hashref returned by the plugin's `run` method. Plugins are also run automatically when you call `check_url`: my $results = $inspector->check_url('https://example.com'); That result will include both built-in checks and plugin checks. ## Example Plugin Here is a minimal example plugin that checks whether the page contains the string "Hello": package SEO::Inspector::Plugin::HelloCheck; use strict; use warnings; sub new { bless {}, shift } sub run { my ($self, $html) = @_; if ($html =~ /Hello/) { return { name => 'Hello Check', status => 'ok', notes => 'found Hello' }; } else { return { name => 'Hello Check', status => 'warn', notes => 'no Hello' }; } } 1; Place this file under `lib/SEO/Inspector/Plugin/HelloCheck.pm` (or another directory listed in `plugin_dirs`), and it will be discovered automatically. ## Naming Conventions The plugin key stored in `$inspector->{plugins}` is derived from the final part of the package name, lowercased. For example: SEO::Inspector::Plugin::HelloCheck -> "hellocheck" This is the key you will see in the hashref returned by `check_html` or `check_url`. # METHODS ## new(%args) Create a new inspector object. Accepts optional `url` and `plugin_dirs` arguments. If `plugin_dirs` isn't given, it tries hard to find the right place. ## load\_plugins Loads plugins from the `SEO::Inspector::Plugin` namespace. ## check($check\_name, $html) Run a single built-in check or plugin on provided HTML (or fetch from object URL if HTML not provided). ## run\_all($html) Run all built-in checks on HTML (or object URL). ## check\_html($html) Run all loaded plugins on HTML. ## check\_url($url) Fetch the URL and run all plugins and built-in checks. # AUTHOR Nigel Horne, `` # SEE ALSO Test coverage report: [https://nigelhorne.github.io/SEO-Inspector/coverage/](https://nigelhorne.github.io/SEO-Inspector/coverage/) - [https://github.com/nigelhorne/SEO-Checker](https://github.com/nigelhorne/SEO-Checker) - [https://github.com/sethblack/python-seo-analyzer](https://github.com/sethblack/python-seo-analyzer) # REPOSITORY [https://github.com/nigelhorne/SEO-Inspector](https://github.com/nigelhorne/SEO-Inspector) # SUPPORT This module is provided as-is without any warranty. Please report any bugs or feature requests to `bug-seo-inspector at rt.cpan.org`, or through the web interface at [http://rt.cpan.org/NoAuth/ReportBug.html?Queue=SEO-Inspector](http://rt.cpan.org/NoAuth/ReportBug.html?Queue=SEO-Inspector). I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. You can find documentation for this module with the perldoc command. perldoc SEO::Inspector You can also look for information at: - MetaCPAN [https://metacpan.org/dist/SEO-Inspector](https://metacpan.org/dist/SEO-Inspector) - RT: CPAN's request tracker [https://rt.cpan.org/NoAuth/Bugs.html?Dist=SEO-Inspector](https://rt.cpan.org/NoAuth/Bugs.html?Dist=SEO-Inspector) - CPAN Testers' Matrix [http://matrix.cpantesters.org/?dist=SEO-Inspector](http://matrix.cpantesters.org/?dist=SEO-Inspector) - CPAN Testers Dependencies [http://deps.cpantesters.org/?module=SEO::Inspector](http://deps.cpantesters.org/?module=SEO::Inspector) # LICENCE AND COPYRIGHT Copyright 2010-2025 Nigel Horne. Usage is subject to licence terms. The licence terms of this software are as follows: - Personal single user, single computer use: GPL2 - All other users (including Commercial, Charity, Educational, Government) must apply in writing for a licence for use from Nigel Horne at the above e-mail.