PHPackages                             wzj177/geo-friendly - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. wzj177/geo-friendly

ActiveLibrary

wzj177/geo-friendly
===================

Generative Engine Optimization for PHP - Make your site discoverable by AI answer engines

20PHPCI failing

Since Mar 26Pushed 1mo agoCompare

[ Source](https://github.com/wzj177/geo-friendly)[ Packagist](https://packagist.org/packages/wzj177/geo-friendly)[ RSS](/packages/wzj177-geo-friendly/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)DependenciesVersions (1)Used By (0)

Geo-Friendly
============

[](#geo-friendly)

[![Latest Version](https://camo.githubusercontent.com/59c172de73ca655e1e629baa758d847c686ab0f2ca77e401de7d3e32020a4e87/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f777a6a3137372f67656f2d667269656e646c79)](https://packagist.org/packages/wzj177/geo-friendly)[![PHP Version](https://camo.githubusercontent.com/b9cc5d507cb69c4b888cda758c81c0f338c97f9eef3614609beff96b58b7e1ab/68747470733a2f2f696d672e736869656c64732e696f2f7068702f762f777a6a3137372f67656f2d667269656e646c79)](https://packagist.org/packages/wzj177/geo-friendly)

Generative Engine Optimization (GEO) for PHP - Make your website discoverable by AI answer engines like ChatGPT, Claude, and Perplexity.

[简体中文文档](README.zh-CN.md)

What is GEO?
------------

[](#what-is-geo)

GEO (Generative Engine Optimization) optimizes content for AI-powered answer engines. This package generates standard files that AI engines use to understand and index your website.

Features
--------

[](#features)

- **AI-Friendly Files**: `llms.txt`, `llms-full.txt`, `robots.txt`, `sitemap.xml`, `docs.json`, `ai-index.json`, `schema.json`
- **CLI Tool**: Simple command-line interface
- **Two Modes**: Local markdown files OR Firecrawl API (for dynamic sites)
- **Content Arrays**: Direct support for database-stored content
- **Platform Ready**: WordPress, Shopify, Laravel, Symfony integrations

Requirements
------------

[](#requirements)

- PHP 7.4+
- Composer
- Extensions: `json`, `simplexml`, `yaml`

Installation
------------

[](#installation)

```
composer require wzj177/geo-friendly
```

Quick Start
-----------

[](#quick-start)

### Method 1: CLI Tool (Recommended for static sites)

[](#method-1-cli-tool-recommended-for-static-sites)

```
# Create config file
vendor/bin/geo init

# Edit geofriendly.yaml, then generate
vendor/bin/geo generate
```

**geofriendly.yaml**:

```
title: 'My Site'
url: 'https://example.com'
contentDir: './content'  # Local markdown files
outDir: './public'
```

### Method 2: Content Arrays (For database content)

[](#method-2-content-arrays-for-database-content)

```
use GeoFriendly\GeoFriendly;

$contents = [
    [
        'title' => 'Getting Started',
        'url' => '/getting-started',
        'content' => '# Getting Started\n\nThis is the content...',
        'description' => 'Learn how to get started',
        'category' => 'guide',
    ],
    [
        'title' => 'API Reference',
        'url' => '/api/reference',
        'content' => '# API Reference\n\n...',
        'description' => 'Complete API documentation',
        'category' => 'api',
    ],
];

$config = [
    'title' => 'My Documentation',
    'url' => 'https://docs.example.com',
    'outDir' => __DIR__ . '/public',
    'contents' => $contents,  // Pass content array
];

$geo = new GeoFriendly($config);
[$generated, $errors] = $geo->generate();
```

### Method 3: Firecrawl (For any website)

[](#method-3-firecrawl-for-any-website)

```
title: 'My Store'
url: 'https://store.example.com'
contentDir: ''  # Empty = use Firecrawl
firecrawl:
  apiKey: 'your-api-key'
  enabled: true
```

Generated Files
---------------

[](#generated-files)

FilePurpose`llms.txt`LLM discovery (per [llms-txt.org](https://llms-txt.org))`llms-full.txt`Complete documentation for AI training`robots.txt`AI crawler permissions`sitemap.xml`SEO sitemap`docs.json`Structured documentation index`ai-index.json`AI-optimized content index`schema.json`Schema.org structured dataCLI Commands
------------

[](#cli-commands)

```
vendor/bin/geo generate          # Generate all files
vendor/bin/geo init             # Create geofriendly.yaml
vendor/bin/geo check            # Audit GEO status
vendor/bin/geo report           # Generate detailed report
```

Content Array Format
--------------------

[](#content-array-format)

When passing content from database:

```
$contents = [
    [
        'title' => string,        // Required: Page title
        'url' => string,          // Required: Page URL (e.g., '/getting-started')
        'content' => string,      // Required: Markdown content
        'description' => string,  // Optional: AI-friendly description (9-10 words)
        'category' => string,     // Optional: Content category
        'tags' => array,          // Optional: Content tags
    ],
    // ... more items
];
```

Usage Scenarios
---------------

[](#usage-scenarios)

### 1. Static Sites with Markdown (VitePress, Docusaurus, Hugo)

[](#1-static-sites-with-markdown-vitepress-docusaurus-hugo)

```
title: 'My Docs'
url: 'https://docs.example.com'
contentDir: './content'
firecrawl:
  enabled: false
```

**Example**: [examples/vitepress-site](examples/vitepress-site)

### 2. Dynamic Sites (WordPress, Shopify)

[](#2-dynamic-sites-wordpress-shopify)

```
title: 'My WordPress Site'
url: 'https://mysite.com'
contentDir: ''
firecrawl:
  apiKey: '%env(FIRECRAWL_API_KEY)%'
  enabled: true
```

**Example**: [examples/wordpress-firecrawl](examples/wordpress-firecrawl)

### 3. Custom Backend (SaaS, Enterprise)

[](#3-custom-backend-saas-enterprise)

```
// Fetch from database
$contents = Content::where('status', 'published')
    ->get()
    ->map(fn($c) => [
        'title' => $c->title,
        'url' => $c->slug,
        'content' => $c->markdown_content,
        'description' => $c->description,
    ])
    ->toArray();

$config = [
    'title' => 'My Platform',
    'url' => 'https://app.example.com',
    'outDir' => storage_path('geo'),
    'contents' => $contents,
];

$geo = new GeoFriendly($config);
[$generated, $errors] = $geo->generate();
```

**Full Guide**: [docs/generic-backend-solution.md](docs/generic-backend-solution.md)

Documentation
-------------

[](#documentation)

- [Content Modes](docs/content-modes.md) - Local files vs Firecrawl
- [AI Integration](docs/AI-INTEGRATION.md) - OpenAI enhancement
- [Backend Solution](docs/generic-backend-solution.md) - Database integration

License
-------

[](#license)

MIT

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance60

Regular maintenance activity

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/d737e52c1e5bb0b14d8d5b8f7297439c45a4d353ab4da3fd1cdd2cd8570a9885?d=identicon)[wzj177](/maintainers/wzj177)

---

Top Contributors

[![jiechengyang](https://avatars.githubusercontent.com/u/33148475?v=4)](https://github.com/jiechengyang "jiechengyang (48 commits)")

### Embed Badge

![Health badge](/badges/wzj177-geo-friendly/health.svg)

```
[![Health](https://phpackages.com/badges/wzj177-geo-friendly/health.svg)](https://phpackages.com/packages/wzj177-geo-friendly)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
