# 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, `