A user lands on your site, sees a generic list of articles, and leaves within 10 seconds. The content isn't relevant; interest is lost. We've encountered dozens of such projects: content exists but engagement is low. AI recommendations solve this—they analyze behavior and deliver personalized content. Our experience: over 20 projects in this niche, guaranteeing at least a 30% increase in page depth. Implementation proceeds without performance degradation, with A/B testing at every stage.
Why AI Recommendations Increase Page Depth
Personalization directly impacts metrics. Content-based approaches boost engagement by 20–40%, collaborative filtering by 50–70%, and hybrid systems up to 80%. We use A/B testing to find the optimal algorithm for your site. The final improvement depends on data quality and the chosen model.
How to Set Up Event Tracking Without Performance Loss
Behavioral data is the foundation for any recommendation. We implement a client-side tracker that sends events via sendBeacon. This doesn't block rendering or affect Core Web Vitals. We analyze views, scrolls, reading time. All data is aggregated in PostgreSQL and used to train models. Tracking is configurable with flexible filtering—we collect only the needed signals, avoiding noise.
Comparison of Recommendation Approaches
| Approach | Data | Complexity | When to Apply |
|---|---|---|---|
| Content-based (embeddings) | Only content | Low | New site, small audience |
| Collaborative filtering | Interaction history | Medium | 10K+ users |
| Hybrid | Content + behavior | High | Media, blogs, news sites |
| LLM-based | Content + profile | Medium | Personalized collections with explanations |
Content-Based: Quick Start with Embeddings
The fastest way to get relevant recommendations is to find similar articles by vector distance. We use OpenAI's text-embedding-3-small model to create embeddings. Indexing happens on publication, and search is done via pgvector. Cosine similarity between vectors gives a similarity metric. Accuracy is 85-90% on test sets.
import OpenAI from 'openai';
import { sql } from '@vercel/postgres';
const openai = new OpenAI();
async function indexArticle(article) {
const textToEmbed = [
article.title,
article.excerpt,
article.tags.join(', '),
article.body.slice(0, 2000),
].join('\n\n');
const { data: [{ embedding }] } = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: textToEmbed,
});
await sql`
UPDATE articles
SET embedding = ${JSON.stringify(embedding)}::vector
WHERE id = ${article.id}
`;
}
async function getSimilarArticles(articleId, limit = 6) {
const result = await sql`
WITH source AS (
SELECT embedding FROM articles WHERE id = ${articleId}
)
SELECT
a.id, a.title, a.slug, a.excerpt, a.published_at,
a.category, a.read_time,
1 - (a.embedding <=> source.embedding) AS similarity
FROM articles a, source
WHERE a.id != ${articleId}
AND a.published = true
AND a.embedding IS NOT NULL
ORDER BY a.embedding <=> source.embedding
LIMIT ${limit}
`;
return result.rows;
}
How to filter irrelevant results?
We set a similarity threshold: articles with cosine similarity below 0.7 are excluded. We also consider category—articles from other sections are not shown. This boosts accuracy by 15%.Collaborative Filtering: When Data is Plentiful
Matrix factorization via implicit feedback (views, time on page). We use the implicit library with the AlternatingLeastSquares algorithm. The model is trained server-side and saved for fast predictions. Training frequency is once per day.
import implicit
import numpy as np
from scipy.sparse import csr_matrix
import pickle
def train_collaborative_model():
events = fetch_events_from_db()
users = {u: i for i, u in enumerate(events['user_id'].unique())}
items = {a: i for i, a in enumerate(events['article_id'].unique())}
rows = events['user_id'].map(users)
cols = events['article_id'].map(items)
data = events['weight']
matrix = csr_matrix((data, (rows, cols)))
model = implicit.als.AlternatingLeastSquares(
factors=128, regularization=0.01, iterations=50, use_gpu=False
)
model.fit(matrix)
with open('/models/collab_model.pkl', 'wb') as f:
pickle.dump({'model': model, 'users': users, 'items': items}, f)
Hybrid System: Best of Both Worlds
We combine content-based, collaborative, and trending signals with weights. Content-based is faster, but hybrid yields 20% more clicks. Example implementation with weights 0.4, 0.5, 0.1:
async function getPersonalizedRecommendations(userId, currentArticleId) {
const [contentBased, collaborative, trending] = await Promise.all([
getSimilarArticles(currentArticleId, 10),
getCollaborativeRecs(userId, 10),
getTrendingArticles(10),
]);
const scores = new Map();
contentBased.forEach((article, i) => {
scores.set(article.id, (scores.get(article.id) || 0) + (10 - i) * 0.4);
});
collaborative.forEach((article, i) => {
scores.set(article.id, (scores.get(article.id) || 0) + (10 - i) * 0.5);
});
trending.forEach((article, i) => {
scores.set(article.id, (scores.get(article.id) || 0) + (10 - i) * 0.1);
});
const allArticleIds = [...scores.keys()];
const articles = await fetchArticlesByIds(allArticleIds);
return articles
.map(a => ({ ...a, score: scores.get(a.id) }))
.sort((a, b) => b.score - a.score)
.slice(0, 6);
}
LLM Recommendations with Explanations
For personalized collections with understandable justifications, we use GPT-4o-mini. Users see not only the recommendation but also the reason: 'Because you read about React.' This boosts trust and click-through rate by 25%.
What's Included
Each implementation stage is completed with artifact delivery. The final package includes:
- Tracking schema and configured client-side tracker
- Recommendation API with documentation (OpenAPI)
- Metrics and A/B test dashboard (Grafana/Tableau)
- Access to the model and code repository
- Team training and text instructions
- 30-day support guarantee post-deployment
We don't just deploy code—we hand over a tool you can customize yourself.
Implementation Stages
| Stage | Duration | Result |
|---|---|---|
| Analytics and design | 1–2 days | Tracking schema, algorithm selection |
| Tracker integration | 1–2 days | Events flowing into database |
| Model training | 2–5 days | Working recommend API |
| A/B testing | 3–7 days | Statistically significant metrics |
| Optimization and deploy | 1–2 days | Production-ready version |
Timelines and Cost
Timelines range from 3 days for a basic pgvector solution to 3 weeks for a full hybrid system with LLM. Cost is calculated individually after audit. We guarantee results contractually. Request AI recommendation implementation and get engagement growth. Contact us for a consultation—we'll assess your project and propose an optimal solution.







