Skip to main content
The userReviews() method retrieves a user’s written reviews from their ČSFD profile. Unlike ratings, reviews include the full review text and movie poster.

Signature

csfd.userReviews(
  user: string | number,
  config?: CSFDUserReviewsConfig,
  options?: CSFDOptions
): Promise<CSFDUserReviews[]>

Parameters

user
string | number
required
User identifier. Can be:
  • User ID as number: 195357
  • Username string: '195357-verbal'
  • Username without ID: 'verbal'
You can find this in the user’s profile URL: https://www.csfd.cz/uzivatel/195357-verbal/
config
CSFDUserReviewsConfig
Configuration options for filtering and pagination
options
CSFDOptions
Override default options for this request

Returns

CSFDUserReviews[]
array
Array of user reviews

Examples

Basic Usage

import { csfd } from 'node-csfd-api';

// Get latest reviews
const reviews = await csfd.userReviews(195357);

reviews.forEach(review => {
  console.log(`${review.title} (${review.year})`);
  console.log(`Rating: ${review.userRating}/5`);
  console.log(`Review: ${review.text}`);
  console.log('---');
});

Get Specific Page

// Get second page of reviews
const page2 = await csfd.userReviews('195357-verbal', { page: 2 });

// Get third page
const page3 = await csfd.userReviews('195357-verbal', { page: 3 });

Fetch All Reviews with Rate Limiting

// Fetch all reviews with 2-second delay between requests
const allReviews = await csfd.userReviews('195357-verbal', {
  allPages: true,
  allPagesDelay: 2000 // 2 seconds between requests
});

console.log(`User has written ${allReviews.length} reviews`);

Filter by Content Type

// Get only movie reviews (exclude series, episodes, etc.)
const onlyMovies = await csfd.userReviews('195357-verbal', {
  includesOnly: ['film']
});

// Get reviews for films and TV films
const moviesAndTvFilms = await csfd.userReviews('195357-verbal', {
  includesOnly: ['film', 'tv-film']
});

// Exclude episode reviews
const noEpisodes = await csfd.userReviews('195357-verbal', {
  excludes: ['episode', 'season']
});

Display Reviews with Posters

const reviews = await csfd.userReviews(195357);

reviews.forEach(review => {
  console.log(`\n${review.title} (${review.year})`);
  console.log(`Poster: ${review.poster}`);
  console.log(`Rating: ${'⭐'.repeat(review.userRating)}`);
  console.log(`Date: ${review.userDate}`);
  console.log(`\nReview:\n${review.text}`);
  console.log('\n' + '='.repeat(50));
});

Find Reviews by Rating

const reviews = await csfd.userReviews('195357-verbal');

// Get 5-star reviews only
const topReviews = reviews.filter(r => r.userRating === 5);

console.log('Movies the user loved:');
topReviews.forEach(review => {
  console.log(`  - ${review.title}: ${review.text.substring(0, 100)}...`);
});

// Get negative reviews (1-2 stars)
const negativeReviews = reviews.filter(r => r.userRating <= 2);

Search Review Text

const reviews = await csfd.userReviews('195357-verbal', {
  allPages: true,
  allPagesDelay: 2000
});

// Find reviews mentioning specific keywords
const keyword = 'výborný';
const matching = reviews.filter(r => 
  r.text.toLowerCase().includes(keyword.toLowerCase())
);

console.log(`Found ${matching.length} reviews mentioning "${keyword}"`);

Export Reviews to Markdown

import { csfd } from 'node-csfd-api';
import { writeFileSync } from 'fs';

async function exportReviewsToMarkdown(userId: string) {
  const reviews = await csfd.userReviews(userId, {
    allPages: true,
    allPagesDelay: 2000
  });
  
  const markdown = [
    '# My ČSFD Reviews',
    '',
    ...reviews.map(r => `
## ${r.title} (${r.year})

**Rating:** ${'⭐'.repeat(r.userRating)}
**Date:** ${r.userDate}
**URL:** ${r.url}

![Poster](${r.poster})

${r.text}

---
`)
  ].join('\n');
  
  writeFileSync(`${userId}-reviews.md`, markdown);
  console.log(`Exported ${reviews.length} reviews`);
}

await exportReviewsToMarkdown('195357-verbal');

Calculate Review Statistics

const reviews = await csfd.userReviews(195357, {
  allPages: true,
  allPagesDelay: 2000
});

// Average review length
const avgLength = reviews.reduce((sum, r) => 
  sum + r.text.length, 0
) / reviews.length;

// Longest review
const longest = reviews.reduce((prev, current) => 
  current.text.length > prev.text.length ? current : prev
);

console.log(`Total reviews: ${reviews.length}`);
console.log(`Average length: ${Math.round(avgLength)} characters`);
console.log(`Longest review: ${longest.title} (${longest.text.length} chars)`);

Compare with Ratings

import { csfd } from 'node-csfd-api';

const userId = '195357-verbal';

// Get both ratings and reviews
const [ratings, reviews] = await Promise.all([
  csfd.userRatings(userId),
  csfd.userReviews(userId)
]);

console.log(`Total ratings: ${ratings.length}`);
console.log(`Written reviews: ${reviews.length}`);
console.log(`Review percentage: ${((reviews.length / ratings.length) * 100).toFixed(1)}%`);

Using Different User ID Formats

// All of these are valid:
const reviews1 = await csfd.userReviews(195357);
const reviews2 = await csfd.userReviews('195357');
const reviews3 = await csfd.userReviews('195357-verbal');

Rate Limiting

When using allPages: true, ČSFD may detect automated requests and temporarily block your IP. Always use allPagesDelay with a reasonable value (2000-5000ms recommended).
// Good - with delay
const reviews = await csfd.userReviews('195357-verbal', {
  allPages: true,
  allPagesDelay: 3000 // 3 seconds
});

// Bad - no delay (may get blocked)
const reviews = await csfd.userReviews('195357-verbal', {
  allPages: true
});

Build docs developers (and LLMs) love