Laravel SEO - This is a simple and extensible package for improving SEO via meta tags, such as OpenGraph tags.

Related tags

Laravel laravel seo
Overview

Laravel SEO

This is a simple and extensible package for improving SEO via meta tags, such as OpenGraph tags.

By default, it uses </code> and OpenGraph tags. It also ships with a Twitter extension. You're, of course, free to write your own extensions as needed.</p> <p><strong>Features</strong>:</p> <ul> <li>Setting SEO tags from PHP</li> <li>Setting SEO tags from Blade</li> <li>Integration with <a href="https://useflipp.com" rel="nofollow">Flipp</a>, to automatically generate cover images</li> <li>Custom extension support</li> <li>Expressive & simple API</li> <li>Customizable views</li> </ul> <p>Example usage:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo() ->title($post->title) ->description($post->excerpt) ->twitter() ->flipp('blog') // Adds OpenGraph tags // Adds Twitter card tags // Generates social image using Flipp and sets it as the cover photo "> <pre><span class="pl-en">seo</span>() -><span class="pl-en">title</span>(<span class="pl-s1"><span class="pl-c1">$</span>post</span>-><span class="pl-c1">title</span>) -><span class="pl-en">description</span>(<span class="pl-s1"><span class="pl-c1">$</span>post</span>-><span class="pl-c1">excerpt</span>) -><span class="pl-en">twitter</span>() -><span class="pl-en">flipp</span>(<span class="pl-s">'blog'</span>) <span class="pl-c">// Adds OpenGraph tags</span> <span class="pl-c">// Adds Twitter card tags</span> <span class="pl-c">// Generates social image using Flipp and sets it as the cover photo</span></pre> </div> <h2><a id="user-content-installation" class="anchor" aria-hidden="true" href="#installation"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Installation</h2> <div class="highlight highlight-source-shell position-relative" data-snippet-clipboard-copy-content="composer require archtechx/laravel-seo "> <pre>composer require archtechx/laravel-seo</pre> </div> <p>And add the following line to your layout file's <code><head></code> tag:</p> <div class="highlight highlight-text-html-basic position-relative" data-snippet-clipboard-copy-content="<x-seo::meta /> "> <pre><span class="pl-kos"><</span><span class="pl-ent">x-seo::meta</span> /></pre> </div> <h2><a id="user-content-usage" class="anchor" aria-hidden="true" href="#usage"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Usage</h2> <p>The package can be used from any PHP code, or specifically from Blade using the <code>@seo</code> directive.</p> <h3><a id="user-content-php" class="anchor" aria-hidden="true" href="#php"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>PHP</h3> <p>Use the <code>seo()</code> helper to retrieve the SeoManager instance, on which you can call the following methods:</p> <p>Available methods:</p> <div class="highlight highlight-source-js position-relative" data-snippet-clipboard-copy-content="site(string $site) url(string $url) title(string $title) description(string $description) image(string $url) twitterSite(string $username) twitterTitle(string $title) twitterDescription(string $description) twitterImage(string $url) "> <pre><span class="pl-en">site</span><span class="pl-kos">(</span><span class="pl-s1">string</span> <span class="pl-s1">$site</span><span class="pl-kos">)</span> <span class="pl-en">url</span><span class="pl-kos">(</span><span class="pl-s1">string</span> <span class="pl-s1">$url</span><span class="pl-kos">)</span> <span class="pl-en">title</span><span class="pl-kos">(</span><span class="pl-s1">string</span> <span class="pl-s1">$title</span><span class="pl-kos">)</span> <span class="pl-en">description</span><span class="pl-kos">(</span><span class="pl-s1">string</span> <span class="pl-s1">$description</span><span class="pl-kos">)</span> <span class="pl-en">image</span><span class="pl-kos">(</span><span class="pl-s1">string</span> <span class="pl-s1">$url</span><span class="pl-kos">)</span> <span class="pl-en">twitterSite</span><span class="pl-kos">(</span><span class="pl-s1">string</span> <span class="pl-s1">$username</span><span class="pl-kos">)</span> <span class="pl-en">twitterTitle</span><span class="pl-kos">(</span><span class="pl-s1">string</span> <span class="pl-s1">$title</span><span class="pl-kos">)</span> <span class="pl-en">twitterDescription</span><span class="pl-kos">(</span><span class="pl-s1">string</span> <span class="pl-s1">$description</span><span class="pl-kos">)</span> <span class="pl-en">twitterImage</span><span class="pl-kos">(</span><span class="pl-s1">string</span> <span class="pl-s1">$url</span><span class="pl-kos">)</span></pre> </div> <p>Example usage:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->title('foo')->description('bar') "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">title</span>(<span class="pl-s">'foo'</span>)-><span class="pl-en">description</span>(<span class="pl-s">'bar'</span>)</pre> </div> <h3><a id="user-content-blade-views" class="anchor" aria-hidden="true" href="#blade-views"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Blade views</h3> <p>You can use the <code>@seo</code> directive to call the methods from Blade:</p> <div class="highlight highlight-text-html-basic position-relative" data-snippet-clipboard-copy-content="@seo('title') // Echoes the title @seo('title', 'foo') // Sets the title & echoes it @seo(['title' => 'foo']) // Sets the title without echoing it "> <pre>@seo('title') // Echoes the title @seo('title', 'foo') // Sets the title & echoes it @seo(['title' =<span class="pl-kos">></span> 'foo']) // Sets the title without echoing it</pre> </div> <p>In general, you'll want to use <code>@seo(['title' => 'foo'])</code> at the start of a view — to set the values — and <code>@seo('title')</code> inside the view if you wish to fetch the value.</p> <p>That is, if you'll use the helpers in Blade at all. Some apps will only use the PHP helper.</p> <p>For Twitter, use the <code>twitter.author</code> format, e.g. <code>@seo('twitter.author')</code>.</p> <h3><a id="user-content-twitter" class="anchor" aria-hidden="true" href="#twitter"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Twitter</h3> <p>By default, no Twitter tags will be included. If you manually enable the extension by calling:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->twitter(); "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">twitter</span>();</pre> </div> <p>in a service provider for example, the extension will be enabled.</p> <p>Once it's enabled, it will copy all default (OpenGraph) values and use them for the Twitter card schema.</p> <p>When a value is set specifically for Twitter, it will be prioritized over the general fallback values.</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->twitterTitle('About us') "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">twitterTitle</span>(<span class="pl-s">'About us'</span>)</pre> </div> <h3><a id="user-content-defaults" class="anchor" aria-hidden="true" href="#defaults"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Defaults</h3> <p>To configure default values, call the methods with the <code>default</code> argument:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo() ->title(default: 'ArchTech — Meticulously architected web applications') ->description(default: 'We are a web development agency that ...'); "> <pre><span class="pl-en">seo</span>() -><span class="pl-en">title</span>(default: <span class="pl-s">'ArchTech — Meticulously architected web applications'</span>) -><span class="pl-en">description</span>(default: <span class="pl-s">'We are a web development agency that ...'</span>);</pre> </div> <h3><a id="user-content-extra-tags" class="anchor" aria-hidden="true" href="#extra-tags"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Extra tags</h3> <p>To add more tags to the document head, you can use the <code>tag()</code> and <code>rawTag()</code> methods:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->tag('fb:image', asset('foo')); seo()->rawTag('<meta property="fb:url" content="bar" />'); seo()->rawTag('fb_url', '<meta property="fb:url" content="bar" />'); // Keyed, allows overrides later on "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">tag</span>(<span class="pl-s">'fb:image'</span>, <span class="pl-en">asset</span>(<span class="pl-s">'foo'</span>)); <span class="pl-en">seo</span>()-><span class="pl-en">rawTag</span>(<span class="pl-s">'<meta property="fb:url" content="bar" />'</span>); <span class="pl-en">seo</span>()-><span class="pl-en">rawTag</span>(<span class="pl-s">'fb_url'</span>, <span class="pl-s">'<meta property="fb:url" content="bar" />'</span>); <span class="pl-c">// Keyed, allows overrides later on</span></pre> </div> <h3><a id="user-content-canonical-url" class="anchor" aria-hidden="true" href="#canonical-url"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Canonical URL</h3> <p>To enable the <code>og:url</code> and canonical URL <code>link</code> tags, call:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->withUrl(); "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">withUrl</span>();</pre> </div> <p>This will make the package read from <code>request()->url()</code> (the current URL <em>without</em> the query string).</p> <p>If you wish to change the URL, call <code>seo()->url()</code>:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->url(route('products.show', $this->product)); "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">url</span>(<span class="pl-en">route</span>(<span class="pl-s">'products.show'</span>, <span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>-><span class="pl-c1">product</span>));</pre> </div> <h3><a id="user-content-modifiers" class="anchor" aria-hidden="true" href="#modifiers"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Modifiers</h3> <p>You may want to modify certain values before they get inserted into the template. For example, you may want to suffix the meta <code><title></code> with <code>| ArchTech</code> when it has a non-default value.</p> <p>To do that, simply add the <code>modify</code> argument to the method calls like this:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->title(modify: fn (string $title) => $title . ' | ArchTech'); "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">title</span>(modify: <span class="pl-en">fn</span> (string <span class="pl-s1"><span class="pl-c1">$</span>title</span>) => <span class="pl-s1"><span class="pl-c1">$</span>title</span> . <span class="pl-s">' | ArchTech'</span>);</pre> </div> <p>You can, of course, combine these with the defaults:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->title( default: 'ArchTech — Meticulously architected web applications', modify: fn (string $title) => $title . ' | ArchTech' ); "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">title</span>( default: <span class="pl-s">'ArchTech — Meticulously architected web applications'</span>, modify: <span class="pl-en">fn</span> (string <span class="pl-s1"><span class="pl-c1">$</span>title</span>) => <span class="pl-s1"><span class="pl-c1">$</span>title</span> . <span class="pl-s">' | ArchTech'</span> );</pre> </div> <p>Which will make the package use the default if no title is provided, and if a title is provided using e.g. <code>seo()->title('Blog')</code>, it will be modified <strong>right before being inserted into the template</strong>.</p> <h3><a id="user-content-flipp-integration" class="anchor" aria-hidden="true" href="#flipp-integration"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Flipp integration</h3> <p>First, you need to add your Flipp API keys:</p> <ol> <li>Add your API key to the <code>FLIPP_KEY</code> environment variable. You can get the key <a href="https://useflipp.com/settings/profile/api" rel="nofollow">here</a>.</li> <li>Go to <code>config/services.php</code> and add: <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="'flipp' => [ 'key' => env('FLIPP_KEY'), ], "> <pre><span class="pl-s">'flipp'</span> => [ <span class="pl-s">'key'</span> => <span class="pl-en">env</span>(<span class="pl-s">'FLIPP_KEY'</span>), ],</pre> </div> </li> </ol> <p>Then, register your templates, for example in <code>AppServiceProvider</code>:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->flipp('blog', 'v8ywdwho3bso'); seo()->flipp('page', 'egssigeabtm7'); "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">flipp</span>(<span class="pl-s">'blog'</span>, <span class="pl-s">'v8ywdwho3bso'</span>); <span class="pl-en">seo</span>()-><span class="pl-en">flipp</span>(<span class="pl-s">'page'</span>, <span class="pl-s">'egssigeabtm7'</span>);</pre> </div> <p>After that, you can use the templates by calling <code>seo()->flipp()</code> like this:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->flipp('blog', ['title' => 'Foo', 'content' => 'bar'])` "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">flipp</span>(<span class="pl-s">'blog'</span>, [<span class="pl-s">'title'</span> => <span class="pl-s">'Foo'</span>, <span class="pl-s">'content'</span> => <span class="pl-s">'bar'</span>])`</pre> </div> <p>The call will set the generated image as the OpenGraph and Twitter card images. The generated URLs are signed.</p> <p>If no data array is provided, the method will use the <code>title</code> and <code>description</code> from the current SEO config:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->title($post->title); seo()->description($post->excerpt); seo()->flipp('blog'); "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">title</span>(<span class="pl-s1"><span class="pl-c1">$</span>post</span>-><span class="pl-c1">title</span>); <span class="pl-en">seo</span>()-><span class="pl-en">description</span>(<span class="pl-s1"><span class="pl-c1">$</span>post</span>-><span class="pl-c1">excerpt</span>); <span class="pl-en">seo</span>()-><span class="pl-en">flipp</span>(<span class="pl-s">'blog'</span>);</pre> </div> <p>The <code>flipp()</code> method also returns a signed URL to the image, which lets you use it in other places, such as blog cover images.</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="<img alt="@seo('title')" src="@seo('flipp', 'blog')"> "> <pre><img alt=<span class="pl-s">"@seo('title')"</span> src=<span class="pl-s">"@seo('flipp', 'blog')"</span>></pre> </div> <h2><a id="user-content-examples" class="anchor" aria-hidden="true" href="#examples"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Examples</h2> <h3><a id="user-content-service-provider" class="anchor" aria-hidden="true" href="#service-provider"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Service Provider</h3> <p>This example sets the default state in a service provider's <code>boot()</code> method:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo() ->site('ArchTech — Meticulously architected web applications') ->title( default: 'ArchTech — Meticulously architected web applications', modify: fn (string $title) => $title . ' | ArchTech' ) ->description(default: 'We are a development agency ...') ->image(default: fn () => asset('header.png')) ->flipp('blog', 'o1vhcg5npgfu') ->twitterSite('archtechx'); "> <pre><span class="pl-en">seo</span>() -><span class="pl-en">site</span>(<span class="pl-s">'ArchTech — Meticulously architected web applications'</span>) -><span class="pl-en">title</span>( default: <span class="pl-s">'ArchTech — Meticulously architected web applications'</span>, modify: <span class="pl-en">fn</span> (string <span class="pl-s1"><span class="pl-c1">$</span>title</span>) => <span class="pl-s1"><span class="pl-c1">$</span>title</span> . <span class="pl-s">' | ArchTech'</span> ) -><span class="pl-en">description</span>(default: <span class="pl-s">'We are a development agency ...'</span>) -><span class="pl-en">image</span>(default: <span class="pl-en">fn</span> () => <span class="pl-en">asset</span>(<span class="pl-s">'header.png'</span>)) -><span class="pl-en">flipp</span>(<span class="pl-s">'blog'</span>, <span class="pl-s">'o1vhcg5npgfu'</span>) -><span class="pl-en">twitterSite</span>(<span class="pl-s">'archtechx'</span>);</pre> </div> <h3><a id="user-content-controller" class="anchor" aria-hidden="true" href="#controller"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Controller</h3> <p>This example configures SEO metadata from a controller.</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="public function show(Post $post) { seo() ->title($post->title) ->description(Str::limit($post->content, 50)) ->flipp('blog', ['title' => $page->title, 'content' => $page->excerpt]); return view('blog.show', compact($post)); } "> <pre><span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">show</span>(<span class="pl-smi">Post</span> <span class="pl-s1"><span class="pl-c1">$</span>post</span>) { <span class="pl-en">seo</span>() -><span class="pl-en">title</span>(<span class="pl-s1"><span class="pl-c1">$</span>post</span>-><span class="pl-c1">title</span>) -><span class="pl-en">description</span>(<span class="pl-v">Str</span>::<span class="pl-en">limit</span>(<span class="pl-s1"><span class="pl-c1">$</span>post</span>-><span class="pl-c1">content</span>, <span class="pl-c1">50</span>)) -><span class="pl-en">flipp</span>(<span class="pl-s">'blog'</span>, [<span class="pl-s">'title'</span> => <span class="pl-s1"><span class="pl-c1">$</span>page</span>-><span class="pl-c1">title</span>, <span class="pl-s">'content'</span> => <span class="pl-s1"><span class="pl-c1">$</span>page</span>-><span class="pl-c1">excerpt</span>]); <span class="pl-k">return</span> <span class="pl-en">view</span>(<span class="pl-s">'blog.show'</span>, <span class="pl-en">compact</span>(<span class="pl-s1"><span class="pl-c1">$</span>post</span>)); }</pre> </div> <h3><a id="user-content-view" class="anchor" aria-hidden="true" href="#view"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>View</h3> <p>This example uses a Blade view that sets global SEO config using the values that are passed to the view.</p> <div class="highlight highlight-text-html-basic position-relative" data-snippet-clipboard-copy-content="@seo(['title' => $page->name]) @seo(['description' => $page->excerpt]) @seo(['flipp' => 'content']) <h1>{{ $page->title }}</h1> <p>{{ $page->excerpt }}</p> <p class="prose"> {{ $page->body }} </p> "> <pre>@seo(['title' =<span class="pl-kos">></span> $page-<span class="pl-kos">></span>name]) @seo(['description' =<span class="pl-kos">></span> $page-<span class="pl-kos">></span>excerpt]) @seo(['flipp' =<span class="pl-kos">></span> 'content']) <span class="pl-kos"><</span><span class="pl-ent">h1</span><span class="pl-kos">></span>{{ $page-<span class="pl-kos">></span>title }}<span class="pl-kos"></</span><span class="pl-ent">h1</span><span class="pl-kos">></span> <span class="pl-kos"><</span><span class="pl-ent">p</span><span class="pl-kos">></span>{{ $page-<span class="pl-kos">></span>excerpt }}<span class="pl-kos"></</span><span class="pl-ent">p</span><span class="pl-kos">></span> <span class="pl-kos"><</span><span class="pl-ent">p</span> <span class="pl-c1">class</span>="<span class="pl-s">prose</span>"<span class="pl-kos">></span> {{ $page-<span class="pl-kos">></span>body }} <span class="pl-kos"></</span><span class="pl-ent">p</span><span class="pl-kos">></span></pre> </div> <h2><a id="user-content-customization" class="anchor" aria-hidden="true" href="#customization"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Customization</h2> <p>This package is completely flexible, and can be customized either by having its views modified (to change the existing templates), or by you developing an extension (to add more templates).</p> <h3><a id="user-content-views" class="anchor" aria-hidden="true" href="#views"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Views</h3> <p>You can publish the Blade views by running <code>php artisan vendor:publish --tag=seo-views</code>.</p> <h3><a id="user-content-extensions" class="anchor" aria-hidden="true" href="#extensions"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Extensions</h3> <p>To use a custom extension, create a Blade <em>component</em> with the desired meta tags. The component should read data using <code>{{ seo()->get('foo') }}</code> or <code>@seo('foo')</code>.</p> <p>For example:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="<meta name="facebook-title" content="@seo('facebook.foo')"> "> <pre><meta name=<span class="pl-s">"facebook-title"</span> content=<span class="pl-s">"@seo('facebook.foo')"</span>></pre> </div> <p>Once your view is created, register the extension:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->extension('facebook', view: 'my-component'); // The extension will use <x-my-component> "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">extension</span>(<span class="pl-s">'facebook'</span>, view: <span class="pl-s">'my-component'</span>); <span class="pl-c">// The extension will use <x-my-component></span></pre> </div> <p>To set data for an extension (in our case <code>facebook</code>), simply prefix calls with the extension name in camelCase, or use the <code>->set()</code> method:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->facebookFoo('bar'); seo()->facebookTitle('About us'); seo()->set('facebook.description', 'We are a web development agency that ...'); seo(['facebook.description' => 'We are a web development agency that ...']); "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">facebookFoo</span>(<span class="pl-s">'bar'</span>); <span class="pl-en">seo</span>()-><span class="pl-en">facebookTitle</span>(<span class="pl-s">'About us'</span>); <span class="pl-en">seo</span>()-><span class="pl-en">set</span>(<span class="pl-s">'facebook.description'</span>, <span class="pl-s">'We are a web development agency that ...'</span>); <span class="pl-en">seo</span>([<span class="pl-s">'facebook.description'</span> => <span class="pl-s">'We are a web development agency that ...'</span>]);</pre> </div> <p>To disable an extension, set the second argument in the <code>extension()</code> call to false:</p> <div class="highlight highlight-text-html-php position-relative" data-snippet-clipboard-copy-content="seo()->extension('facebook', false); "> <pre><span class="pl-en">seo</span>()-><span class="pl-en">extension</span>(<span class="pl-s">'facebook'</span>, <span class="pl-c1">false</span>);</pre> </div> <h2><a id="user-content-development" class="anchor" aria-hidden="true" href="#development"> <svg class="octicon octicon-link" viewbox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"> <path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path> </svg></a>Development</h2> <p>Run all checks locally:</p> <div class="highlight highlight-source-shell position-relative" data-snippet-clipboard-copy-content="./check "> <pre>./check</pre> </div> <p>Code style will be automatically fixed by php-cs-fixer.</p> </article> </div> </div> </div> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-7963911354665843" data-ad-slot="8874001906"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <div id="issues" class="card mt-3"> <div class="card-header"><h5>Comments</h5></div> <div class="card-body"> <div class="review-list"> <ul> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/315686?v=4" class="lazy profile-pict-img img-fluid" alt="Seo blade tag to set social image?"> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/22" rel="nofollow"> Seo blade tag to set social image? </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>The <code>@seo</code> blade tag can set e.g. the description like this <code>@seo(['description' => 'foo'])</code>. But I didn't find any way to do the same for the social image? The following call (which I expected to work) resulted in an error:</p> <pre><code class="language-plain">ArchTech\SEO\SEOManager::set(): Argument #2 ($value) must be of type Closure|string|null, array given, called in /Users/tpetry/Documents/laravel-seo/src/SEOManager.php on line 95 </code></pre> <pre><code class="language-php">@seo(['flipp' => ['blog', ['title' => 'Lorem Ipsum', 'description' => 'Lorem Ipsum, Lorem Ipsum']]]) ```php Is it not supported to set the social image with the `@seo` tag without returning any value or did I just miss the correct call?</code></pre> </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by tpetry <i class="fa fa-commenting" aria-hidden="true"></i> 7 </span> </div> </div> </li> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/5972548?v=4" class="lazy profile-pict-img img-fluid" alt="Is it possible to use different content for the title and the og:title?"> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/15" rel="nofollow"> Is it possible to use different content for the title and the og:title? </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>Is it possible to use different content for the title and og:title?</p> <p>So for example.</p> <pre><code><title>Article Title | Category | Website</title> <meta property="og:title" content="Article Title"/> </code></pre> <p>I have tried using the following but the <strong>'og:title'</strong> only appears twice.</p> <pre><code>seo()->title('Article Title | Category | Website'); seo()->tag('og:title', 'Article Title.'); </code></pre> <p>...</p> <pre><code><title>Article Title | Category | Website</title> <meta property="og:title" content="Article Title | Category | Website"/> <meta property="og:title" content="Article Title"/> </code></pre> <span style='padding: .2em .6em .3em;color:#fff;background-color:#a2eeef'>enhancement</span>  </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by grafxflow <i class="fa fa-commenting" aria-hidden="true"></i> 6 </span> </div> </div> </li> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/5972548?v=4" class="lazy profile-pict-img img-fluid" alt="Possible to change the og:type"> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/16" rel="nofollow"> Possible to change the og:type </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>Is it possible to add an option to change the <strong>og:type</strong> ?</p> <p>So things like 'website', 'article'.</p> <p><code>seo()->type('article')</code></p> <p>But always keeping 'website' as the default fall back setting.</p> <span style='padding: .2em .6em .3em;color:#fff;background-color:#a2eeef'>enhancement</span>  </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by grafxflow <i class="fa fa-commenting" aria-hidden="true"></i> 5 </span> </div> </div> </li> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/47271716?v=4" class="lazy profile-pict-img img-fluid" alt="Updated PHP doc blocks to aid IDEs when using named arguments."> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/5" rel="nofollow"> Updated PHP doc blocks to aid IDEs when using named arguments. </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>I've updated the doc blocks within SEOManager.php as the current ones trigger an error on IDEs such as PHPStorm. The current docs make it seem that only ($title) is allowed, however the exact code from the package documentation show <code>default</code> and <code>modifier</code>, which result in IDE complaining it doesn't exist.</p> <p>This PR has fixed my original issue, and also doesn't affect usage without named arguments.</p> </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by heychazza <i class="fa fa-commenting" aria-hidden="true"></i> 4 </span> </div> </div> </li> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/315686?v=4" class="lazy profile-pict-img img-fluid" alt="Add twitter:creator meta tag"> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/21" rel="nofollow"> Add twitter:creator meta tag </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>Additionally to the <code>twitter:site</code> meta tag, this Pull Request adds the <code>creator</code> one to indicate who is responsible for the article instead of the whole site.</p> </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by tpetry <i class="fa fa-commenting" aria-hidden="true"></i> 1 </span> </div> </div> </li> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/13846420?v=4" class="lazy profile-pict-img img-fluid" alt="HTML tag spacing strange"> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/19" rel="nofollow"> HTML tag spacing strange </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>Hey team,</p> <p>How come when using the <code><x-seo::meta /></code> tag, it inputs the HTML all strange? It adds tabs randomly, adds new lines randomly, and joins some things together on the same line. Why not just input everything one line after eachother?</p> <p>Controller Code:</p> <pre><code> seo() ->title('News & Updates - MySite') ->description('Find out the latest') ->site('MySite') ->twitter(); </code></pre> <p>Actual HTML output:</p> <pre><code><title>News & Updates - MySite</title>   <meta property="og:title" content="News & Updates - MySite" />   <meta property="og:description" content="Find out the latest" /> <meta name="description" content="Find out the latest" />   <meta property="og:type" content="website" /> <meta property="og:site_name" content="MySite">   <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="MySite"> <meta name="twitter:title" content="News & Updates - MySite"> <meta name="twitter:description" content="Find out the latest"> </code></pre> </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by idealerror <i class="fa fa-commenting" aria-hidden="true"></i> 1 </span> </div> </div> </li> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/952007?v=4" class="lazy profile-pict-img img-fluid" alt="Fixing all PHPStan problems"> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/9" rel="nofollow"> Fixing all PHPStan problems </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>We need dev-master from PHPStan and https://github.com/nunomaduro/larastan/pull/946</p> <pre><code class="language-diff">diff --git a/composer.json b/composer.json index 6c0e997..3e62416 100644 --- a/composer.json +++ b/composer.json @@ -29,9 +29,10 @@ }, "require-dev": { "orchestra/testbench": "^6.9", - "nunomaduro/larastan": "^0.6.10", + "nunomaduro/larastan": "dev-master", "pestphp/pest": "^1.2", - "pestphp/pest-plugin-laravel": "^1.0" + "pestphp/pest-plugin-laravel": "^1.0", + "phpstan/phpstan": "dev-master as 0.12.90" }, "extra": { "laravel": { diff --git a/phpstan.neon b/phpstan.neon index f586106..a04c137 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,11 +10,9 @@ parameters: universalObjectCratesClasses: - Illuminate\Routing\Route - ArchTech\SEO\SEOManager + checkMissingIterableValueType: false ignoreErrors: - - '#SEOManager\|array\|string\|null#' - - '#string\|false given#' - - '#flipp\(\) should return#' - - '#\_\_set\(\) has no return typehint specified#' - - checkMissingIterableValueType: false + # Waiting for https://github.com/phpstan/phpstan/issues/5706 + - '#^Cannot call method (flipp|get|set)\(\) on ArchTech\\SEO\\SEOManager\|array\|string\|null\.$#' + - '#^Method ArchTech\\SEO\\SEOManager::flipp\(\) should return static\(ArchTech\\SEO\\SEOManager\)\|string but returns array\|string\|null\.$#' diff --git a/src/SEOManager.php b/src/SEOManager.php index d036034..d68a98f 100644 --- a/src/SEOManager.php +++ b/src/SEOManager.php @@ -82,11 +82,14 @@ class SEOManager : value($this->values[$key]); } - /** Set one or more values. */ + /** + * Set one or more values. + * + * @param string|array<string, string> $key + */ public function set(string|array $key, string|Closure|null $value = null): string|array|null { if (is_array($key)) { - /** @var array<string, string> $key */ foreach ($key as $k => $v) { $this->set($k, $v); } @@ -166,7 +169,7 @@ class SEOManager ]; } - $query = base64_encode(json_encode($data)); + $query = base64_encode((string)json_encode($data)); /** @var string $template */ $template = $this->meta("flipp.templates.$alias"); @@ -273,7 +276,11 @@ class SEOManager return $this->get(Str::snake($key, '.')); } - /** Handle magic set. */ + /** + * Handle magic set. + * + * @phpstan-return string|array|null + */ public function __set(string $key, string $value) { return $this->set(Str::snake($key, '.'), $value); diff --git a/src/helpers.php b/src/helpers.php index 658df88..9a8e8f1 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -5,14 +5,21 @@ declare(strict_types=1); use ArchTech\SEO\SEOManager; if (! function_exists('seo')) { + /** + * @template T of string|array + * @param T|null $key + * @return SEOManager|string|array|null + */ function seo(string|array $key = null): SEOManager|string|array|null { - if (! $key) { + if ($key === null) { return app('seo'); - } elseif (is_array($key)) { + } + + if (is_array($key)) { return app('seo')->set($key); - } else { - return app('seo')->get($key); } + + return app('seo')->get($key); } } </code></pre> <p>It is 100% up to you! This is an inspiration, not code.</p> </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by szepeviktor <i class="fa fa-commenting" aria-hidden="true"></i> 1 </span> </div> </div> </li> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/952007?v=4" class="lazy profile-pict-img img-fluid" alt="Multifunctional methods"> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/8" rel="nofollow"> Multifunctional methods </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>Hello! While resolving all ignored PHPStan errors I've bumped into methods like <code>SEOManager::meta</code>. Or the <code>seo</code> function.</p> <p>Please consider using 1 method for 1 thing.</p> <blockquote> <p>Get or set metadata.</p> </blockquote> <p>The "S" in <a href="https://en.wikipedia.org/wiki/SOLID">SOLID</a>.</p> </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by szepeviktor <i class="fa fa-commenting" aria-hidden="true"></i> 1 </span> </div> </div> </li> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/47271716?v=4" class="lazy profile-pict-img img-fluid" alt="Raw tags cannot be overridden"> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/6" rel="nofollow"> Raw tags cannot be overridden </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>When using raw tags (with the keys), it only adds additional HTML entries into the header, I know the concept behind it is to override as we spoke about previously. I personally use this for favicons, where I change it for viewing pages with user uploaded avatars.</p> <p>When diving further, your tests (as found https://github.com/archtechx/laravel-seo/blob/master/tests/Pest/ManagerTest.php#L102) seem to reference the wrong value. Shouldn't this be checking for the newer entry, rather than the original abc?</p> </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by heychazza <i class="fa fa-commenting" aria-hidden="true"></i> 1 </span> </div> </div> </li> <li> <div class="d-flex"> <div class="left"> <span> <img data-original="https://avatars.githubusercontent.com/u/315686?v=4" class="lazy profile-pict-img img-fluid" alt="Add previewify prefix"> </span> </div> <div class="right"> <h4> <a href="https://github.com/archtechx/laravel-seo/issues/24" rel="nofollow"> Add previewify prefix </a> </h4> <div class="review-description"> <article class="markdown-body text-wrap"> <p>As discussed in #23 Previewify data keys need a prefix to work correctly. I changed the implementation to your recommendation of automatically prefixing the keys.</p> </article> </div> <span class="publish py-3 d-inline-block w-100"> opened by tpetry <i class="fa fa-commenting" aria-hidden="true"></i> 0 </span> </div> </div> </li> </ul> </div> </div> </div> <div id="releases" class="card mt-3"> <div class="card-header"><h5>Releases(v0.5.1)</h5></div> <div class="card-body"> <div class="review-list"> <ul> <li> <div class="d-flex"> <div class="right"> <h4> v0.5.1(Jul 5, 2022) </h4> <div class="review-description"> <article class="markdown-body"> <h2>What's Changed</h2> <ul> <li>Add previewify prefix by @tpetry in https://github.com/archtechx/laravel-seo/pull/24</li> </ul> <p><strong>Full Changelog</strong>: https://github.com/archtechx/laravel-seo/compare/v0.5.0...v0.5.1</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.5.1">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.5.1">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.5.0(Jun 11, 2022) </h4> <div class="review-description"> <article class="markdown-body"> <h2>What's Changed</h2> <ul> <li>Add twitter:creator meta tag by @tpetry in https://github.com/archtechx/laravel-seo/pull/21</li> <li>Add Previewify image provider by @tpetry in https://github.com/archtechx/laravel-seo/pull/20</li> </ul> <h2>New Contributors</h2> <ul> <li>@tpetry made their first contribution in https://github.com/archtechx/laravel-seo/pull/21</li> </ul> <p><strong>Full Changelog</strong>: https://github.com/archtechx/laravel-seo/compare/v0.4.0...v0.5.0</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.5.0">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.5.0">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.4.0(Mar 30, 2022) </h4> <div class="review-description"> <article class="markdown-body"> <h2>What's Changed</h2> <ul> <li>OpenGraph improvements by @stancl in https://github.com/archtechx/laravel-seo/pull/17</li> <li>Support setting different <code>title</code> and <code>og:title</code> #15</li> <li>Support setting <code>og:type</code> #16</li> </ul> <h2>New Contributors</h2> <ul> <li>@stancl made their first contribution in https://github.com/archtechx/laravel-seo/pull/17</li> </ul> <p><strong>Full Changelog</strong>: https://github.com/archtechx/laravel-seo/compare/v0.3.2...v0.4.0</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.4.0">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.4.0">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.3.2(Feb 8, 2022) </h4> <div class="review-description"> <article class="markdown-body"> <h2>What's Changed</h2> <ul> <li>Add support for Laravel 9 by @abrardev99 in https://github.com/archtechx/laravel-seo/pull/14</li> </ul> <h2>New Contributors</h2> <ul> <li>@abrardev99 made their first contribution in https://github.com/archtechx/laravel-seo/pull/14</li> </ul> <p><strong>Full Changelog</strong>: https://github.com/archtechx/laravel-seo/compare/v0.3.1...v0.3.2</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.3.2">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.3.2">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.3.1(Nov 16, 2021) </h4> <div class="review-description"> <article class="markdown-body"> <p>Improved code quality & static analysis.</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.3.1">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.3.1">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.3.0(Nov 15, 2021) </h4> <div class="review-description"> <article class="markdown-body"> <p>Added <code>favicon()</code> method, thanks @Larsklopstra!</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.3.0">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.3.0">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.2.2(May 28, 2021) </h4> <div class="review-description"> <article class="markdown-body"> <p>Improve IDE support, fix raw tag overrides</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.2.2">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.2.2">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.2.1(May 27, 2021) </h4> <div class="review-description"> <article class="markdown-body"> <p>meta description</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.2.1">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.2.1">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.2.0(May 26, 2021) </h4> <div class="review-description"> <article class="markdown-body"> <p>Bump minor version</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.2.0">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.2.0">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.1.8(May 26, 2021) </h4> <div class="review-description"> <article class="markdown-body"> <p>Canonical URLs #1, extra tags #2</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.1.8">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.1.8">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.1.1(May 24, 2021) </h4> <div class="review-description"> <article class="markdown-body"> <p>Fix composer autoregistration</p> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.1.1">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.1.1">Source code(zip)</a><br> </article> </div> </div> </div> </li> <li> <div class="d-flex"> <div class="right"> <h4> v0.1.0(May 24, 2021) </h4> <div class="review-description"> <article class="markdown-body"> <i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/tarball/v0.1.0">Source code(tar.gz)</a><br><i class="fa fa-file-code-o m-r-xs" aria-hidden="true"></i><a href="https://api.github.com/repos/archtechx/laravel-seo/zipball/v0.1.0">Source code(zip)</a><br> </article> </div> </div> </div> </li> </ul> </div> </div> </div> </div> <div class="col-lg-4 right"> <div id="basic" class="tab-pane fade show active"> <div class="box shadow-sm rounded bg-white mb-3"> <div class="box-title border-bottom p-3"> <h6 class="m-0">Owner </h6> </div> <div class="d-flex align-items-center p-3 job-item-header"> <div class="overflow-hidden mr-2"> <h6 class="font-weight-bold -dark mb-0 text-truncate"> ARCHTECH </h6> <div class="small text-gray-500"> Meticulously architected web applications. </div> </div> <img class="img-fluid ml-auto" style="border-radius: 50%;" src="https://avatars.githubusercontent.com/u/84272491?v=4&s=60" alt="ARCHTECH"> </div> <div class="box-body p-3"> <a href="https://github.com/archtechx/laravel-seo" rel="nofollow" target="_blank" class="btn btn-lg btn-block btn-info mb-3"><i class="fa fa-github" aria-hidden="true"></i> GitHub </a> <a href="https://archte.ch/blog/introducing-laravel-seo" rel="nofollow" target="_blank" class="btn btn-lg btn-block btn-dark mb-3"><i class="fa fa-home" aria-hidden="true"></i> https://archte.ch/blog/introducing-laravel-seo</a> </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/eusonlito-laravel-Meta"><h6 class="font-weight-bold ">HTML Meta Tags management package available for for Laravel 5.*</h6></a> <p class="mb-0 text-muted">HTML Meta Tags management package available for Laravel 5/6/7/8 With this package you can manage header Meta Tags from Laravel controllers. If you wan</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/644551?v=4&s=40" alt="Lito" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 182 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Dec 5, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/ayvazyan10-laravel-seo-hook-for-jsframeworks"><h6 class="font-weight-bold ">Simple laravel hook for adding meta tags to head for inertia</h6></a> <p class="mb-0 text-muted">laravel seo hook for js frameworks simple hook for adding meta tags to <head></head> for js frameworks inertia:react,vue, etc... in app/Meta.php put M</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/79054971?v=4&s=40" alt="Razmik Ayvazyan" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 2 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Aug 23, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/ARCANEDEV-SEO-Helper-php-laravel-utilities"><h6 class="font-weight-bold ">SEO Helper is a package that provides tools and helpers for SEO (Search Engine Optimization).</h6></a> <p class="mb-0 text-muted">SEO Helper By ARCANEDEV© SEO Helper is a package that provides tools and helpers for SEO (Search Engine Optimization). Feel free to check out the rele</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/9376707?v=4&s=40" alt="ARCANEDEV" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 301 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Nov 25, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/armancodes-laravel-download-link-php-laravel-utilities"><h6 class="font-weight-bold ">A simple Laravel package for generating download links with options such as expire time, IP restrictions, etc.</h6></a> <p class="mb-0 text-muted">Generate download links in your Laravel applications This package allows you to generate download links for files. Once installed you can do stuff lik</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/22839699?v=4&s=40" alt="Arman Ahmadi" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 12 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Nov 24, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/hwavina-hwa-meta"><h6 class="font-weight-bold ">Laravel package meta 🧡</h6></a> <p class="mb-0 text-muted">About hwa-meta is a meta package. It helps us to build and develop faster with pre-built functions. This saves a lot of time on future projects. We sh</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/76942961?v=4&s=40" alt="Hwavina" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 3 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Oct 18, 2021 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/touhidurabir-laravel-meta-fields-php-laravel-utilities"><h6 class="font-weight-bold ">A laravel package to handle model specific additional meta fields in an elegant way.</h6></a> <p class="mb-0 text-muted">Laravel Meta Fields A php package for laravel framework to handle model meta data in a elegant way. Installation Require the package using composer: c</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/2587979?v=4&s=40" alt="Touhidur Rahman" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 26 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Apr 5, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/magesuite-magesuite"><h6 class="font-weight-bold ">The main MageSuite (meta)package to rule them all</h6></a> <p class="mb-0 text-muted">A Magento 2 extension ecosystem providing UX/performance improvements and many new features. This is a core metapackage which you should install in or</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/42670934?v=4&s=40" alt="MageSuite" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 166 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Dec 14, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/Labs64-laravel-boilerplate-php-laravel-utilities"><h6 class="font-weight-bold ">Laravel Boilerplate provides a very flexible and extensible way of building your custom Laravel applications.</h6></a> <p class="mb-0 text-muted">Laravel Boilerplate Project Laravel Boilerplate provides a very flexible and extensible way of building your custom Laravel applications. Table of Con</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/1461983?v=4&s=40" alt="Labs64" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 848 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Dec 28, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/aravel-breeze-is-a-php-laravel-library-that-provides-authentication-features-such-as-login-page--register-reset-password-and-creating-all-sessions-re"><h6 class="font-weight-bold ">Laravel breeze is a PHP Laravel library that provides Authentication features such as Login page , Register, Reset Password and creating all Sessions Required.</h6></a> <p class="mb-0 text-muted">About Laravel breeze To give you a head start building your new Laravel application, we are happy to offer authentication and application starter kits</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/61456675?v=4&s=40" alt="null" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 3 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Jul 30, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/tripflex-wp-job-manager-empty-meta-cleanup"><h6 class="font-weight-bold ">Clean up and prevent empty meta from being saved for Job, Company, or Resume listings in database</h6></a> <p class="mb-0 text-muted">=== Empty Meta Cleanup for WP Job Manager === Contributors: tripflex Tags: wp job manager, meta, cleanup, wpjobmanager Requires at least: 5.2 Tested u</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/553732?v=4&s=40" alt="Myles McNamara" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 3 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Feb 7, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/ralphjsmit-laravel-filament-seo"><h6 class="font-weight-bold ">A convenient helper for using the laravel-seo package with Filament Admin and Forms</h6></a> <p class="mb-0 text-muted">Combine the power of Laravel SEO and Filament PHP. This package is a convenient helper for using the laravel-seo package with Filament Admin and Forms</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/59207045?v=4&s=40" alt="Ralph J. Smit" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 39 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Dec 21, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/hoaproject-Ruler"><h6 class="font-weight-bold ">Hoa is a modular, extensible and structured set of PHP libraries</h6></a> <p class="mb-0 text-muted">Hoa is a modular, extensible and structured set of PHP libraries. Moreover, Hoa aims at being a bridge between industrial and research worlds. Hoa\Rul</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/1519718?v=4&s=40" alt="Hoa" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 624 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Dec 30, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/michael-rubel-laravel-seo-manager"><h6 class="font-weight-bold ">Manage meta data based on URL path within your app.</h6></a> <p class="mb-0 text-muted">Laravel SEO Manager This package provides simple functionality to manage SEO tags based on URL path within your Laravel application. You can put the U</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/37669560?v=4&s=40" alt="Michael Rubel" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 20 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Oct 20, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/dominiquevienne-laravel_magic"><h6 class="font-weight-bold ">Laravel magical helpers such as Controllers / Requests / Models</h6></a> <p class="mb-0 text-muted">Laravel Magic provides Abstract Controller, Model, generic Request, Traits, Exceptions and various middlewares in order to generate very easily and quickly API resources from scratch.</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/4158499?v=4&s=40" alt="Dominique Vienne" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 1 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Sep 1, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/lionix-team-seo-manager-php-laravel-utilities"><h6 class="font-weight-bold ">Seo Manager Package for Laravel ( with Localization )</h6></a> <p class="mb-0 text-muted">Seo Manager Package for Laravel ( with Localization ) lionix/seo-manager package will provide you an interface from where you can manage all your page</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/45678688?v=4&s=40" alt="Lionix" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 205 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Dec 23, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/ralphjsmit-laravel-seo"><h6 class="font-weight-bold ">A package to handle the SEO in any Laravel application, big or small.</h6></a> <p class="mb-0 text-muted">Never worry about SEO in Laravel again! Currently there aren't that many SEO-packages for Laravel and the available ones are quite complex to set up a</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/59207045?v=4&s=40" alt="Ralph J. Smit" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 267 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Jan 2, 2023 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/SiroDiaz-laravel-redirection"><h6 class="font-weight-bold ">Laravel package for manage your URL redirects in database or other sources to get better SEO results</h6></a> <p class="mb-0 text-muted">Laravel 8 and 9 package to manage URL redirections inside your Laravel application using different data sources. It allows a better SEO support for your Laravel site.</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/7469286?v=4&s=40" alt="Siro Díaz Palazón" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 51 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Sep 21, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/arif98741-multicourier"><h6 class="font-weight-bold ">This is a courier api endpoints library for interacting such as e-courier, dhl, pathao etc</h6></a> <p class="mb-0 text-muted">This is a courier api endpoints library for interacting such as e-courier, dhl, pathao etc Installation Step 1: composer require xenon/multicourier S</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/17213478?v=4&s=40" alt="Ariful Islam" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 19 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Sep 8, 2022 </div> </div> <div class="box shadow-sm mb-3 rounded bg-white ads-box"> <div class="p-3 border-bottom"> <a href="/repo/tylercd100-lern"><h6 class="font-weight-bold ">LERN is a Laravel package that will record exceptions into a database and will notify you via Email, Pushover or Slack.</h6></a> <p class="mb-0 text-muted">LERN is a Laravel package that will record exceptions into a database and will notify you via Email, Pushover or Slack.</p> </div> <div class="p-2"> <img class="lazy img-fluid mr-3" style="border-radius: 50%;max-width: 15%" data-original="https://avatars.githubusercontent.com/u/4522226?v=4&s=40" alt="Tyler Arbon" > <i class="fa fa-star ml-3" aria-hidden="true"></i> 437 <i class="fa fa-clock-o ml-3" aria-hidden="true"></i> Nov 17, 2022 </div> </div> </div> </div> </div> </div> <!-- footer --> <footer class="bg-white"> <div class="container"> <div class="copyright"> <div class="logo"> <a href="/"> <img src="/assets/images/logo_bestofphp.png"> </a> </div> <p>2022.bestofphp </p> </div> </div> </footer> <!-- footer--> <!-- Bootstrap core JavaScript --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha512-bnIvzh6FU75ZKxp0GXLH9bewza/OIw6dLVh9ICg0gogclmYGguQJWl8U30WpbsGTqbIiAwxTsbe76DErLq5EDQ==" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.bundle.min.js" integrity="sha512-Oy5BruJdE3gP9+LMJ11kC5nErkh3p4Y0GawT1Jrcez4RTDxODf3M/KP3pEsgeOYxWejqy2SPnj+QMpgtvhDciQ==" crossorigin="anonymous"></script> <!-- select2 Js --> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js" integrity="sha512-2ImtlRlf2VVmiGZsjm9bEyhjGW4dU7B6TNwh/hx/iSByxNENtj3WVE6o/9Lj4TJeVXPi4bnOIMXFIJJAeufa0A==" crossorigin="anonymous"></script> <!-- Custom --> <script src="/assets/js/custom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js"></script> <script> $(function() { $("img.lazy").lazyload({ threshold :180, failurelimit :20, effect : "fadeIn" }); }); </script> <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script> <script> hljs.initHighlightingOnLoad(); </script> </body> </html>