Finding related content in a Laravel application often means building custom queries or relying on keyword matching, which misses semantic connections. Laravel Related Content, created by Vladislav Stoitsov, uses vector embeddings and PostgreSQL's pgvector extension to automatically discover and link related content across different model types based on meaning rather than keywords. The package is currently in beta at the time of this writing.
The package pre-computes relationships at save time and stores them as database records, so retrieving related content is a standard database query (~5ms) instead of a real-time similarity search on every page load.
Main Features
- Pre-computed Related Links: Related content is calculated on save, not on every page load
- Fast Lookups: O(1) relationship queries instead of real-time similarity search
- Cross-Model Relationships: Find related content across different model types (e.g. an Article can surface related Events or Community Links)
- Multiple Embedding Providers: Support for OpenAI and Ollama
- Queue Support: Process embeddings in the background
- Semantic Search: Search content by meaning, not just keywords
Getting Started
The package requires PostgreSQL with the pgvector extension. If you haven't enabled it yet, run the following in your database:
CREATE EXTENSION IF NOT EXISTS vector;
After installing the package and running its migrations, configure your embedding provider in .env. For OpenAI:
RELATED_CONTENT_PROVIDER=openaiOPENAI_API_KEY=your-api-keyOPENAI_EMBEDDING_MODEL=text-embedding-3-smallOPENAI_EMBEDDING_DIMENSIONS=1536
Or for a local Ollama instance:
RELATED_CONTENT_PROVIDER=ollamaOLLAMA_BASE_URL=http://localhost:11434OLLAMA_EMBEDDING_MODEL=nomic-embed-textOLLAMA_EMBEDDING_DIMENSIONS=768
Adding Related Content to Models
Add the HasRelatedContent trait to any model and define which fields should be used for generating embeddings:
class Article extends Model{ use HasRelatedContent; public function embeddableFields(): array { return ['title', 'excerpt', 'content']; }}
When a model is saved, the package generates an embedding from the specified fields and finds related content across all configured models.
Retrieving Related Content
Retrieve related models with a single method call:
// Get all related models$related = $article->getRelatedModels(); // Limit the number of results$related = $article->getRelatedModels(5); // Get related models of a specific type$events = $article->getRelatedOfType(Event::class);
Since relationships are pre-computed, these calls are standard database queries with no additional API requests.
Cross-Model Relationships
One of the package's notable features is the ability to link content across different models. Register the models that should participate in cross-model relationships in config/related-content.php, and the package will find connections between them automatically. An article about "Laravel testing" could surface a related conference event or community link on the same topic.
'models' => [ \App\Models\Article::class, \App\Models\Event::class, \App\Models\CommunityLink::class,],
Then, semantically search across all configured models by meaning rather than exact keywords:
$service = app(RelatedContentService::class);$results = $service->search('Laravel AI tools and best practices');
This returns matching content from any registered model type based on the semantic similarity of the query to stored embeddings.
Rebuilding Embeddings
Use the included Artisan command to generate embeddings for existing records or regenerate them after changing embeddable fields:
# Process models that are missing embeddingsphp artisan related-content:rebuild # Process a specific model (missing only)php artisan related-content:rebuild "App\Models\Article" # Regenerate all embeddingsphp artisan related-content:rebuild --force # Process synchronously instead of queuingphp artisan related-content:rebuild --sync
Events
The package also dispatches a RelatedContentSynced event when relationships are updated, allowing you to trigger additional logic such as cache invalidation or notifications.
To learn more about Laravel Related Content and view the source code, visit the GitHub repository.