Giter Club home page Giter Club logo

laravel-seo's Introduction

Hi there 👋 I'm Ralph

I'm a Laravel-developer. Usually I spend my time doing freelance work and my university study (Business Economics). In the meantime I also write about PHP, Laravel, Tailwind & more on my personal blog, ralphjsmit.com. (If you're interested, subscribe to my newsletter to occassionaly receive an email with some updates.)

I love to create Laravel-packages. My most popular open-source package is the ralphjsmit/laravel-seo package, also featured on Laravel News. I'm also a regular contributor to Filament PHP and its ecosystem with plugins and PRs. I'm also the author of three premium packages for Filament: Filament Media Library, Filament Onboarding and Filament Notifications Pro.

I also enjoy open source contributions, so occassionaly you may see PRs from me to Laravel or a package⚡️

laravel-seo's People

Contributors

dejagersh avatar dependabot[bot] avatar github-actions[bot] avatar knightvision90 avatar marcelosantos89 avatar pascalebeier avatar ralphjsmit avatar richdynamix avatar standaniels avatar tjardoo avatar tuimz avatar voltra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

laravel-seo's Issues

Structured data for JobPosting

Hello there,

Great job with the package. As mentioned by you, i come to you to know how to deal with job posting structured data as this is crucial for a lot of web apps who have a Hiring page and want to list that out on google jobs.

Thanks.

Name spacing for Modifying tags before they're sent

I'm struggling with the name spacing example in the readme file:

https://github.com/ralphjsmit/laravel-seo#modifying-tags-before-they-are-rendered

SEOManager::tagTransformer(function (TagCollection $tags): TagCollection {
    $tags = $tags->reject(fn(Tag $tag) => $tag instanceof OpenGraphTag);
    
    $tags->push(new MetaTag(name: 'custom-tag', content: 'My custom content'));
    // Will render: <meta name="custom-tag" content="My custom content">
    
    return $tags;
});

The error is:

TypeError
App\Http\Controllers\PostController::App\Http\Controllers\{closure}(): Argument #1 ($tag) must be of type App\Models\Tag, RalphJSmit\Laravel\SEO\Tags\RobotsTag given

The only one that sort of seems okay so far is this one:

use RalphJSmit\Laravel\SEO\Facades\SEOManager;

Any clues what other name spaces to use? I tried automatic importing in Visual Studio code but ended up with the above error.

[Bug] The package added prefix in the titel

<title>&lt;!--[if BLOCK]&gt;&lt;![endif]--&gt;The Qing | Kuala Lumpur | Pixalink Explore</title>

Hi @ralphjsmit , have been using this package for a long time but from time to time the packages acts weirdly by adding extra "IF BLOCK" to the title and the html tag

I am using exactly versions : * 1.4.3 which is the latest version.
This bug have been causing a big problem to me personally, as you can see at Pixalink Explore.
I have screenshot it for your references.
Screenshot 2024-01-30 at 1 49 38 AM

here's the config

return [
    'model' => SEO::class,

    'site_name' => config('app.name'),

    'sitemap' => '/sitemap.xml',

    'canonical_link' => true,

    'robots' => [
        'default' => 'max-snippet:-1,max-image-preview:large,max-video-preview:-1',

        'force_default' => false,
    ],

    'favicon' => '/icons/Pixalink-Logo-N-150x150.png',

    'title' => [
        'infer_title_from_url' => true,
        'suffix' => ' | '.config('app.name'),
        
        'homepage_title' => config('app.name'),
    ],

    'description' => [
        'fallback' => 'omitted.',
    ],

    'image' => [
        'fallback' => '/Pixalink Full Logo 16-9.webp',
    ],

    'author' => [
        'fallback' => 'Pixalink.io',
    ],

    'twitter' => [
        '@username' => null,
    ],
];

Thanks in advance

Capitalization of locale

Hi there!

I noticed that for e.g. locale = 'nl_NL'; in config/app.php the following meta tag gets output:

<meta property="og:locale" content="nl_nl">

The second NL is lowercases, resulting in nl_nl.

If I look at the opengraph website, I read:

og:locale - The locale these tags are marked up in. Of the format language_TERRITORY. Default is en_US.

The format of the territory should be uppercase. The examples also show en_US or en_GB etc.

I am no expert in SEO, so my question is, is this problematic?

It seems to be happening here in SEOData constructor:

$this->locale = Str::of(app()->getLocale())->lower()->kebab();

Call to undefined method after artisan optimize

After calling php artisan optimize I get always the following error:

Call to undefined method RalphJSmit\Laravel\SEO\Support\SEOData::__set_state() {"exception":"[object] (Error(code: 0): Call to undefined method RalphJSmit\\Laravel\\SEO\\Support\\SEOData::__set_state() at /bootstrap/cache/routes-v7.php:7551)
[stacktrace]
#0 /var/www/clients/client1/web210/web/releases/20240307103309/vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php(108): require()
#1 /var/www/clients/client1/web210/web/releases/20240307103309/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1073): Illuminate\\Foundation\\Support\\Providers\\RouteServiceProvider->Illuminate\\Foundation\\Support\\Providers\\{closure}()
#2 /var/www/clients/client1/web210/web/releases/20240307103309/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1016): Illuminate\\Foundation\\Application->fireAppCallbacks()
#3 /var/www/clients/client1/web210/web/releases/20240307103309/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/BootProviders.php(17): Illuminate\\Foundation\\Application->boot()
#4 /var/www/clients/client1/web210/web/releases/20240307103309/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(263): Illuminate\\Foundation\\Bootstrap\\BootProviders->bootstrap()
#5 /var/www/clients/client1/web210/web/releases/20240307103309/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(186): Illuminate\\Foundation\\Application->bootstrapWith()
#6 /var/www/clients/client1/web210/web/releases/20240307103309/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(170): Illuminate\\Foundation\\Http\\Kernel->bootstrap()
#7 /var/www/clients/client1/web210/web/releases/20240307103309/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#8 /var/www/clients/client1/web210/web/releases/20240307103309/public/index.php(51): Illuminate\\Foundation\\Http\\Kernel->handle()
#9 {main}
"} 

It seems that something in the cache is not working properly:

at bootstrap/cache/routes-v7.php:7599
    7595▕         'view' => 'faq',
    7596▕         'data' => 
    7597▕         array (
    7598▕           'SEOData' => 
  ➜ 7599▕           \RalphJSmit\Laravel\SEO\Support\SEOData::__set_state(array(
 

This has been verified on production server and also in development environment.

If you need further information don't hesitate to contact me.

Compatibility issue with Laravel 10

I'm trying to use this package in my Laravel 10 project, but I'm encountering an error related to compatibility. I believe there is a conflict between the requirements of package and Laravel 10. Can you please help me resolve this issue?

{
    "require": {
        "php": "^8.1",
        "laravel/framework": "^10.0",
        "ralphjsmit/laravel-seo": "^1.1"
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}


Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires laravel/framework ^10.0 -> satisfiable by laravel/framework[10.x-dev].
    - ralphjsmit/laravel-seo[1.1.0, ..., 1.2.2] require illuminate/contracts ^8.79|^9.0 -> satisfiable by illuminate/contracts[v8.79.0, ..., 8.x-dev, v9.0.0-beta.1, ..., 9.x-dev].
    - Only one of these can be installed: illuminate/contracts[v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev, v9.0.0-beta.1, ..., 9.x-dev, 10.x-dev], laravel/framework[10.x-dev]. laravel/framework replaces illuminate/contracts and thus cannot coexist with it.
    - Root composer.json requires ralphjsmit/laravel-seo ^1.1 -> satisfiable by ralphjsmit/laravel-seo[1.1.0, 1.2.0, 1.2.1, 1.2.2].

How to turn the seo into json?

Hi, thank you for the work you've put into developing and maintaining this repo.
I recently have a situation where I needed to retrieve SEO information from an endpoint.
I want to return my seo as json, but right now it is just returns a raw data from database

class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id'             => $this->id,
            'slug'           => $this->slug,
            'title'          => $this->title,
            'excerpt'        => $this->excerpt,
            'content'        => $this->content,
            'seo'            => $this->seo,  // <-- Here...
            'featured_image' => $this->featuredImage,
            'published_at'   => $this->published_at,
            'created_at'     => $this->created_at,
        ];
    }
}

and it returns something like this :

"seo": {
    "id": 2,
    "model_type": "post",
    "model_id": 1,
    "description": "Commodi elit in deb",
    "title": "In vitae rerum quis ",
    "image": null,
    "author": "Leah Mcclain",
    "robots": null,
    "canonical_url": null,
    "created_at": "2023-12-30T09:55:45.000000Z",
    "updated_at": "2023-12-30T09:55:45.000000Z"
},

I was wondering if it could be enhanced to provide more useful information in a JSON format

How to use absolute path to images in seo?

Hello, we are using Vapor to host our application, and it does not use the relative path to the public folder instead, it uses an absolute path which we can get using asset() helper inside the application.

How can I use the absolute path for the images of the products.?

utf 8 for the Arabic language not work good in seo()

this code using seo helper and simple $model->seo->title

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <!-- SEO -->
    {!! seo() !!}
    <!-- End SEO -->


    <!-- simple title -->
    <title>{{$tool->seo->title}}</title>
    <!-- end title -->

this result

ksnip

How to translate the url

I'm in the post page of 'en' version once I switch to 'ar' language the switch is successfull but the url still in english.
This issue creates extra links for sitemap.
I've used the package translate method in routes and links but doesn't work with dynamic post pages. So please tell how to make it. Thanks

"Article Schema Validation": Error for field "dateUpdated" - Should be "dateModified" instead.

I added an "Article Schema" to my SEOData object.

Problem: The $article->dateModified property is rendered as invalid schema field dateUpdated in src/Schema/ArticleSchema.php. The field in the schema should be named dateModified too.

This creates an invalid schema. https://validator.schema.org/ (Article Schema specification: https://schema.org/Article)

Error message of the Schema Validator: "dateUpdated" - The property dateUpdated is not recognized by the schema (e.g. schema.org) for an object of type Article.

1. Set the SEOData object with "dateModified"...

$seoData = new SEOData(
    title: $post->title,
    ...
    schema: SchemaCollection::initialize()->addArticle(
        function (ArticleSchema $article) use ($post) {
            $article->datePublished = $post->published_at;
            $article->dateModified = $post->updated_at;
            $article->addAuthor('Team');
            return $article;
        }
    ),
);

2. Output is created with wrong "dateUpdated" key.

See src/Schema/ArticleSchema.php: Line 88 should be updated to 'dateModified' => $this->dateModified->toIso8601String()

public function generateInner(): string
{
    return collect([
        '@context' => 'https://schema.org',
        '@type' => $this->type,
        'mainEntityOfPage' => [
            '@type' => 'WebPage',
            '@id' => $this->url,
        ],
        'datePublished' => $this->datePublished->toIso8601String(),
        'dateUpdated' => $this->dateModified->toIso8601String(),
        'headline' => $this->headline,
    ])
        ->when($this->authors, fn (Collection $collection): Collection => $collection->put('author', $this->authors))
        ->when($this->description, fn (Collection $collection): Collection => $collection->put('description', $this->description))
        ->when($this->image, fn (Collection $collection): Collection => $collection->put('image', $this->image))
        ->when($this->articleBody, fn (Collection $collection): Collection => $collection->put('articleBody', $this->articleBody))
        ->pipeThrough($this->markupTransformers)
        ->toJson();
}

robots - Allow to set values like "noindex" (in RobotsTags)

I try to set <meta name="robots" content="noindex"> for a Terms & Condition page, but this is not possible.

This is how I think it should work...

$SEOData = new SEOData(
    title: 'Terms & Services',
    description: 'These are our T&C.',
    robots => 'noindex',
);

At the moment, the method RobotsTags::initialize() just pushes the string 'max-snippet:-1,max-image-preview:large,max-video-preview:-1' every time.

$model->seo->update() doesn't create record in seo table

$post = Post::find(1);

$test = $post->seo->update([
   'title' => 'My great post',
   'description' => 'This great post will enhance your live.',
]);

Test returns false and doesn't insert row into seo table.

However the following does work.

$post = Post::find(1);
$seo = $post->seo;
$seo->title = 'My great post;
$seo->description = 'This great post will enhance your live.';
$seo->save();

Laravel version: 10.25.2
PHP version: 8.1.17

getDynamicSEOData(): tags and section don't generate anything

php 8.2.15
laravel/framework 10.43.0
ralphjsmit/laravel-seo 1.4.3

public function getDynamicSEOData(): SEOData
    {
        Log::debug($this->category->name); // content in logs
        Log::debug($this->tags->pluck('name')->toArray()); // content in logs

        return new SEOData(
            title: $this->title,
            description: Str::words($this->description, 30, ''),
            author: $this->user->name,
            section: $this->category->name, // no content in page
            tags: $this->tags->pluck('name')->toArray(), // no content in page
            schema: SchemaCollection::initialize()->addArticle(),
        );
    }

Allow for `<title>` and `og:title` to be different

Currently, there's only one title field in SEO. Often, for SEO and/or UX purposes, the page title and the og:title are different. This is impossible or tedious to do using the package in its current state.

It'd be nice to have an og_title database column that defaults to the value of title.

Class "App\Http\Controllers\SEOData" not found

in my controller :
$seo = new SEOData(

        title: $room->title,

        description: $room->description,

    );

    // return $seo;

    return view('web.pages.roomdetail',compact('room','ruangan','offers','seo'));

Not showing my seo from model, but from defaults

I'm sorry to bother you, I've read the docs again and again... but I can't get {!! (seo($page ?? null)) !!} to show the SEO stored by the seo model...
Is there something I'm missing?

Dumping the seo call at blade {!! dd(seo($page ?? null)) !!}, I get this:

RalphJSmit\Laravel\SEO\TagManager {#2555 ▼ // resources/views/layouts/app.blade.php
  +model: ? Illuminate\Database\Eloquent\Model
  +SEOData: ? RalphJSmit\Laravel\SEO\Support\SEOData
  +tags: 
RalphJSmit\Laravel\SEO
\
TagCollection {#2036 ▼
    #items: array:6 [▶]
    #escapeWhenCastingToString: false
  }
}

with results in defaults for seo:
image

BUT in my controller (PostController) I check the SEO for my post:

    $seo = $post->seo;
    dump($seo->toArray());

I get the correct data:

array:11 [▼ // app/Http/Controllers/PostController.php:15
  "id" => 1
  "model_type" => "App\Models\Post"
  "model_id" => 1
  "description" => "The best description is one that incites the imagination."
  "title" => "Manually set SEO Title at creation/update (test)!!"
  "image" => null
  "author" => "Cyrus Frank"
  "robots" => null
  "canonical_url" => null
  "created_at" => "2024-05-04T08:57:57.000000Z"
  "updated_at" => "2024-05-04T09:50:39.000000Z"
]

How can I get {!! seo() !!} to use the current stored seo data of my post?
Thanks a lot (in advance) :)

It's not possible to generate ImageMeta for images from other sources than images from `public` directory

I am trying to generate ImageMeta for a Post model, which has an image stored in S3. When this image is uploaded, I calculate their dimensions, write that information to my model, and then write the image to S3. ImageMeta only has a constructor for constructing from a public path, which I don't have.

I am currently working around this like this:

$imageMeta = new ImageMeta('images/logo-small.png');

$imageMeta->width = $post->image_width;
$imageMeta->height = $post->image_height;

Which isn't optimal... Is there a different way I should be doing this? Or is a better approach not possible right now? 😬

I have some ideas for improving ImageMeta, but it's a breaking change. Something like this would be much more flexible I think:

readonly class ImageMeta
{
    public function __construct(public int $width, public int $height)
    {
    }

    public static function forPublicImage(string $path): self
    {
        $publicPath = public_path($path);

        if (!is_file($publicPath)) {
            throw new Exception("Path {$publicPath} is not a file.");
        }

        [$width, $height] = getimagesize($publicPath);

        return new self($width, $height);
    }

    public static function forImageFromDisk(Filesystem $filesystem, string $path) {
        stream_copy_to_stream(
            $filesystem->readStream($path),
            $tmpFile = tmpfile()
        );

        [$width, $height] = getimagesize(stream_get_meta_data($tmpFile)['uri']);

        return new self($width, $height);
    }
}

Costume Tags

Hello @ralphjsmit.
Thanks for you package
How can I add costume meta-tags like og:url , og:type etc storing this data on database.
like Costume Proprieties of laravel-Media-library.

Can't render my custom seoData

Hello,
This is probably very simple to resolve. I have set in my Blog model the function getDynamicSEOData

public function getDynamicSEOData(): SEOData
    {
        $language = app()->getLocale();
        return new SEOData(
            title: $this->{'title_'.$language},
            description: $this->{'summary_'.$language},
            author: 'Guy Verville',
            image: $this->getFirstMedia('blog')('seo')
        );
    }

This looks fine.
In my BlogController in the show method, I wrote

$seo=$post->getDynamicSEOData();

[...]

 return view('blog.show', ['content' => $content, 'seoData' => $seo]);

My blog template looks like this:

<x-layout>
    <x-slot:title>{{ $content['title'] }}</x-slot:title>
    <x-slot:translationURL>{{ $content['otherLanguage'] }}</x-slot:translationURL>
    <x-slot:seoData>{{$seoData}}</x-slot:seoData>
    <div class="relative pt-[100px] md:pt-[400px]">
        [...]
</x-layout>

and my layout.blade.php has the {!! seo($seoData !!} or {{ seo($seoData) }} command. However, it get an error the it can pass your object, expects a string, etc.. {!! seo() !!} works fine, but with the default settings.

I have tried a lot of things, with no success. I have difficulty understand what should be passed. In other words, I get the SEO Object, but am unable to reproduce the examples given...

Can you help?

Huge delay with imageMeta when running tests

Hey 👋

I use spatie/laravel-medialibrary for managing files including images. And I noticed when I'm running tests there is a huge stall (around 5-6seconds) on the imageMeta creation. I pass the getFirstMediaUrl to the SEOData and it works fine in browser since it returns a full url to the image (like: http://www....)

view()->share('SEOData', new SEOData(
     image: $category->getFirstMediaUrl(Disk::CategoryPictures),
));

But during tests since the storage is faked, the getFirstMediaUrl returns a local path like /storage/1/.... and this seem to confuse this package's imageMeta() inside SEOData class and the test would get delayed for many seconds until it finally passes.

I wonder if this is something that can be fixed or taken into account for such scenario ?
Or is there a different approach I should take for passing the image path. I'm asking this since spatie/laravel-medialibrary is a popular package and people probably might end up with same pitfall.

Thanks in advance and thank you for your great package 😊🙌

How to keep Image URL parametres unchanged

I'm using Glide library to secure images and any change in the image URL, Glide take it as invalid.
is there a way to keep the URL without skipping parameters ?

example:

https://website.test/images/xSVtl6ZF7fNuZIoXkZbzI2EzoAD.jpg?h=800&amp;fit=contain&amp;q=80&amp;fm=webp

to be like this

https://website.test/images/xSVtl6ZF7fNuZIoXkZbzI2EzoAD.jpg?h=800&fit=contain&q=80&fm=webp

Encoding HTML entities

Hi, there's an encoding inconsistency with HTML entities:

Config:
'homepage_title' => 'Buy & Sell',

Not encoded:
<title>Buy & Sell</title>

Encoded:

<meta property="og:title" content="Buy &amp; Sell">
<meta name="twitter:title" content="Buy &amp; Sell">

mutateFormDataBeforeSave for SEO Plugin

Hi. Thanks for the great plugin.

I started looking at it today and am wondering how I can manipulate the SEO data from the Filament form before it is being saved. The SEO data does not appear in the $data array which is passed to Filament's mutateFormDataBeforeSave method.

I'm wondering if there is a feature where I can set SEO data before being saved to the database (without the user entering data in the form). If I could do this, i could check for null form values in the SEO form fields and then save the SEO data (populated from the model and/or $data values). I still need to give users the option to enter data into the SEO form fields.

I saw the method you have provided getDynamicSEOData and i could use that, but for my use case it will require querying the database for the seo row of the model, checking it for null values, and then returning that. It would be nice if I didn't have to go to that much effort :)

Open Graph Tags not rendered correctly

It seems the default Open Graph tags aren't rendered as should be.

Currently it renders the tag <meta name="og:title" content="Title">, but it should be <meta name="title" property="og:title" content="Title">

So in the OpenGrapTag class, it should not adjust the value of the name, but add property with the value og:[name value].

Title in this case is just an example. It has to be adjusted for all Open Graph tags.

Canonical URL override

Is it possible to override the canonical URL on a page by page basis, rather than only setting in the global config?

It is often required to manually set a canonical url for content that has been syndicated from multiple sources, such as news aggregator sites.

getDynamicSEOData : tags field

Hello,
I'm trying to add post tags (from spatie tags) but it's not rendered,

 public function getDynamicSEOData(): SEOData
    {
        return new SEOData(
            title: $this->name,
            description: $this->short_description,
            author: app(GeneralSettings::class)->site_name,
            image: $this->getImageUrl(),
            tags: $this->getTags(),

        );
    }

$this->getTags() contains :

[
  0 => "test"
  1 => "new"
  2 => "custom"
]

Theses tags doesn't appear in head meta, what's wrong ?

Escaping fields

Any specific reason why the library is not escaping fields?

Since we are required to allow html from

{!! seo()->for($SEOData) !!}

Then when I provide for example custom content like title/description and if it contains any HTML it will render it.

For example:

'SEOData' => new SEOData(
                title: 'Something</title><h1>test</h1><title></title>',
                description: '',
            ),

This will render the test on top of the page.

Sure i can solve the problem by adding e('string') everywhere but its a risk if someone forgets.

Use \Exception instead of PHPUnit exception

in src\Support\ImageMeta.php PHPUnit\Runner\Exception is used instead of \Exception wich causes errors in production (when installing the project without development dependencies)

Tags output order

Hello. Thanks for this package :) Not really an issue, but is it possible to change the output order of the tags? Is there a way to specify it or sort tags before output?

Description tag missing

This is most likely a configuration issue on my end but I cannot figure it out. The meta tags are showing up but description is missing. Using the code below

model

public function getDynamicSEOData(): SEOData
    {
        return new SEOData(
            description: $this->excerpt,
        );
    }

blade

{!! seo($page ?? null) !!}

Error when adding schema Call to a member function toIso8601String() on null

I was adding schema to some pages but I get this error

Call to a member function toIso8601String() on null

my code is bellow

Any suggestions?

        return view('essentials', [
            'SEOData' => new SEOData(
                title: 'Essentials',
                description: 'Essentials Description',
                image: '',
                type: 'article',
                schema: SchemaCollection::initialize()->addArticle(),
            ),
        ]);

adding this to ralphjsmit/laravel-seo/src/Schema/ArticleSchema.php fixes it but i'm not sure if this is the correct solutions

            'datePublished' => $this->datePublished->toIso8601String(),
            'dateModified' => $this->dateModified->toIso8601String(),

to

            'datePublished' => $this->datePublished?->toIso8601String(),
            'dateModified' => $this->dateModified?->toIso8601String(),

How to fill seo information on pages without model

Greetings! Thank you for your job, i have one question:

For example i have Contact page with PagesController@contact method associated with it (it's just returns a view), how can i set own title, description etc. in contact controller method, without model?

Enhance favicon or add ability to override

Hello, thank you for this package!

I took at a look at the favicon tag, and it seems to be barebones.

I'm curious if it's possible to either exclude that tag (so we can define it ourselves), or, to enhance this package with broader favicon support across a variety devices and display sizes.

See this article goes in depth with some of the options and best practices.

As an example, the https://realfavicongenerator.net/ tool generates output like the following, depending on the user's chosen color settings:

<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">

Use in layout

If we have an app.blade.php layout, how do I pass the post to ->for()?

{!! seo()->for($post) !!}

laravel-seo for static pages (without model)

Often I create static pages without any model attached. (See example controller below)

Feature request: It would be great, if I just can fill the plain SEOData() object and pass this object to the layout template.

class Homepage extends Controller
{
    public function index()
    {
        return view('project.frontend.page.homepage.index', [
            'seoData' => new SEOData(
                title: 'Awesome News - My Project',
                description: 'Lorem Ipsum',
            ),
        ]);
    }
}

The $seoData set in the controller is than passed to the layout file and outputted with seo($seoData).

{!! seo($seoData) !!}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.