定制 particle-academy/fancy-seo 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

particle-academy/fancy-seo

Composer 安装命令:

composer require particle-academy/fancy-seo

包简介

Server-rendered SEO + crawlability for Laravel + Inertia apps — per-route meta/Open Graph/Twitter/JSON-LD on the first byte, dynamic sitemap.xml / robots.txt / llms.txt, and per-page Markdown. The PHP baseline that pairs with @particle-academy/fancy-inertia's <Seo>.

README 文档

README

Fancy UI

particle-academy/fancy-seo

Server-rendered SEO + crawlability for Laravel + Inertia apps.

An Inertia/React SPA applies per-page <Head> meta after hydration — so a crawler, social scraper, or LLM bot that hits a URL sees only the bare root view on the first byte. fancy-seo computes the per-route head (title, description, canonical, Open Graph, Twitter, JSON-LD) on the server and renders it into the first byte, plus a dynamic sitemap.xml / robots.txt / llms.txt and an optional per-page Markdown variant.

It's the PHP baseline that pairs with @particle-academy/fancy-inertia/seo's client <Seo> component: the package renders the default head; <Seo> overrides it per page via Inertia's head-key dedupe.

Install

composer require particle-academy/fancy-seo

Laravel auto-discovers the service provider + FancySeo facade. Publish the config if you want to tune it:

php artisan vendor:publish --tag=fancy-seo-config

Wire it up

1. Drop the head component into your root Blade template (e.g. app.blade.php), inside <head>:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <x-fancy-seo::head />

    @vite(['resources/js/app.tsx'])
    @inertiaHead
</head>

That renders <title>, description, canonical, robots, the full Open Graph + Twitter set, the llms.txt alternate link, and one <script type="application/ld+json"> per JSON-LD node — all from the resolved per-route payload.

2. Register defaults + per-route SEO from a service provider:

use FancySeo\Facades\FancySeo;
use FancySeo\JsonLd;

FancySeo::defaults([
    'site_name' => 'Fancy UI',
    'image' => '/og/default.png',
    'twitterSite' => '@particleacademy',
    'jsonLd' => [
        JsonLd::website('Fancy UI', url('/'), searchUrlTemplate: url('/search?q={search_term_string}')),
        JsonLd::softwareApplication('Fancy UI', url('/'), ['applicationCategory' => 'DeveloperApplication', 'operatingSystem' => 'Web', 'price' => '0']),
    ],
]);

FancySeo::route('packages.show', fn (array $params) => [
    'title' => "{$params['package']} — Fancy UI",
    'jsonLd' => [JsonLd::softwareSourceCode($params['package'], url("/packages/{$params['package']}"), "https://github.com/Particle-Academy/{$params['package']}", ['programmingLanguage' => 'TypeScript'])],
]);

FancySeo::noindexRoutes(['admin.*', 'auth.*']);

A controller can also set the payload for the current request:

FancySeo::for(['title' => $post->title, 'description' => $post->excerpt, 'type' => 'article']);

Precedence: defaults() → per-route resolver → resolveUsing()for(). jsonLd accumulates across layers; everything else overrides.

Discovery endpoints

Auto-registered (toggle each in config/fancy-seo.php):

Route What
/sitemap.xml every URL you register via FancySeo::sitemap(...)
/robots.txt crawl policy — welcomes LLM bots, references the sitemap
/llms.txt, /llms-full.txt the llmstxt.org Markdown index you register via FancySeo::llms(...)
/.well-known/security.txt RFC 9116 (only when a contact is configured)
/humans.txt colophon
/{path}.md per-page raw Markdown (opt-in) via FancySeo::markdownUsing(...)
FancySeo::sitemap(function ($map) {
    $map->add('/', '1.0', 'daily');
    foreach (Package::all() as $pkg) {
        $map->add("packages/{$pkg->slug}", '0.8');
    }
});

FancySeo::llms(fn (FancySeo $seo) => view('seo.llms')->render());

FancySeo::markdownUsing(fn (string $path) => MarkdownContent::for($path)); // null → 404

JSON-LD builders

FancySeo\JsonLd mirrors @particle-academy/fancy-inertia/seo's builders — website, organization, softwareApplication, softwareSourceCode, article, breadcrumbList, faqPage, howTo, collectionPage. Each returns a plain array with the @context/@type set; pass them to defaults() / route() / for().

howTo() and faqPage() no longer render as Google rich results, but the markup still strengthens machine understanding + AI answers — emit them only on pages whose visible content genuinely is an ordered how-to / Q&A.

Social images

Set richer Open Graph / Twitter card metadata via the resolved payload (or the image_alt / image_width / image_height config defaults):

FancySeo::for([
    'image' => '/og/react-fancy.png',
    'imageAlt' => 'react-fancy — Tailwind v4 React primitives',
    'imageWidth' => 1200,
    'imageHeight' => 630,
]);

The head component emits og:image:alt|width|height + twitter:image:alt.

Content Security Policy

Under a strict script-src 'nonce-…' CSP, pass the nonce so the inline JSON-LD isn't dropped: <x-fancy-seo::head :nonce="$cspNonce" /> (or set a static fancy-seo.csp_nonce in config).

Validate in CI

php artisan fancy-seo:validate lints every parameter-less, named GET route the way <x-fancy-seo::head> renders it — missing/duplicate titles, thin or over-long descriptions, missing/relative canonicals, noindex leaks, and malformed JSON-LD. Use --format=json|junit for machine output and --strict to fail on warnings:

- run: php artisan fancy-seo:validate --format=junit --strict

Roadmap

Not yet shipped (open an issue if you need them sooner):

  • hreflang locale clusters + reciprocal x-default (for multilingual sites).
  • Sitemap index / chunking for sites above the 50k-URL per-file limit.

License

MIT

⭐ Star Fancy UI

If this package is useful to you, a quick ⭐ on the repo really helps us build a better kit. Thank you!

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-15

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固