# Changelog of Tijelabin Multi-Scraper (tijelabin.com) (`hamza325/tijelabin-multi-scraper`) Actor

- **URL**: https://apify.com/hamza325/tijelabin-multi-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/hamza325/tijelabin-multi-scraper.md

## Changelog

All notable changes to the Tijelabin Multi-Scraper Actor are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### \[3.3] - 2026-10-06

#### Added

- **Paste a URL, the Actor figures out the task.** New **URL** (`pageUrl`) input — the one field a run needs. Paste any tijelabin.com page URL from the browser's address bar and the Actor detects what it points at: a search page (`https://tijelabin.com/search?q=iphone`) runs that search with the link's keyword and page number; a category page (`https://tijelabin.com/category/15/cars`) browses the category; a wilaya or commune page (`https://tijelabin.com/state/alger`, `/city/alger-centre`) browses the location; a store page (`https://tijelabin.com/store/a693b29e82c2ac`) scrapes that seller's listings; a listing page (`https://tijelabin.com/products/8930/tecno-pova-6`) scrapes that listing with full detail data. A results URL starts the walk at the page stated in the link and paginates forward. Pasting a page that names no task (home page, interface pages) fails at startup with a message pointing at the right kind of link.

#### Changed

- **The explicit per-task controls moved into a collapsible "Legacy inputs (advanced)" section.** **What to scrape** (`startMode`) defaults to `auto` (URL detection) and sits at the top of that section, followed by the per-mode fields (**Search keyword**, **Category page URL**, **Location page URL**, **Store page URL**, **Listing URLs**). New runs don't need them; all of them keep working for existing integrations and remain the way to reach the tasks a URL can't express: **Specific listing URLs** (`directUrls`), **Similar products** (`similar`) and **Category tree snapshot** (`categories`). In explicit modes every surface-specific field falls back to `pageUrl` when its own field is empty.

#### Migration

- Runs that set both a URL (`pageUrl`) and the legacy per-mode fields change behavior: the URL now takes precedence in explicit modes too. Remove `pageUrl` to keep the old field-driven behavior. Integrations that relied on `startMode` being required can keep sending it — the explicit values work exactly as before, and omitting `startMode` now means `auto`.

### \[3.2] - 2026-09-17

#### Added

- **Listing rows now carry the wilaya and commune browse URLs.** `stateUrl` (`https://tijelabin.com/state/{slug}`) and `cityUrl` (`https://tijelabin.com/city/{slug}`) accompany the existing slug and name fields on **Specific listing URLs** (`directUrls`) rows, so a listing's location can be fed straight into the **Wilaya / commune page URL** (`locationUrl`) input without rebuilding the link. Both are null on grid-card rows, which carry no location link. The **Listings** dataset view shows the new columns.

### \[3.1] - 2026-09-17

#### Added

- **`Category tree snapshot` mode (`startMode: "categories"`).** Emits one node per category — `id`, `url`, `categoryId`, `categoryLabel` — read from the site's category sitemap (two XML requests, no HTML parsing). The taxonomy is flat: 39 top-level categories, no subcategories. Use a node's `url` as the **Category page URL** (`categoryUrl`) input for a **Browse a category** (`category`) run, or use the snapshot to build a taxonomy of the site. Category rows carry `__type: "tijelabin_category"`; the label is derived from the URL slug because the sitemap carries no display name.

#### Changed

- **Dataset schema `required` relaxed to `id`, `url`, `scrapedAt`.** Category nodes carry no `title`, `currency` or `status`, so those fields are no longer mandatory on every row. Listing rows are unchanged.

### \[3.0] - 2026-09-04

#### Removed

- **The seller-info row in `Store` mode.** `Seller store listings` runs previously emitted one extra row describing the store itself (`__type = "seller"`, carrying `announcementCount` and `followersCount`). Every run now returns listing rows only — each row is one product. This also removes the `__type` output field and the dataset's **Seller** view. One row per store run (the one whose `id` was the store's hex ID) no longer appears.

#### Changed

- **`Store` mode no longer fails with "Schema validation failed".** The removed seller row was the row the dataset schema rejected, so the store-mode crash is gone. The schema's `required` list applies to the uniform listing rows: `id`, `url`, `title`, `currency`, `status`, `scrapedAt`.

#### Migration

- Saved datasets keep their existing rows. New store runs produce listing rows only; delete the old seller-info row (`__type = "seller"`) if you already captured one. Re-push the Actor to pick up the new output schema.

### \[2.1] - 2026-09-04

#### Added

- **`primaryImageUrl` output field.** The first image URL (`images[0]`) is now surfaced as its own scalar so the Apify dataset table renders an image thumbnail per row. The `images` array still carries the full gallery (or the single card thumbnail) for programmatic use — arrays render as an "N items" badge in the table view, so the thumbnail needs a scalar. Grid rows point at the card thumbnail; "Specific listing URLs" rows point at the first HD gallery image. The dataset's **Listings** view now shows the thumbnail and the gallery column.

#### Changed

- **Renamed the Actor to Tijelabin Multi-Scraper.** The previous name ("Tijelabin Scraper") didn't convey that the Actor drives six modes from a single input. The Actor ID on Apify is now `tijelabin-multi-scraper`; the input form, README and dataset output are unchanged except for the new `primaryImageUrl` field. Saved tasks and existing dataset links keep working — only the Actor's display name and ID slug changed.

### \[2.0] - 2026-09-04

A ground-up redesign of the input form around one rule: **every reference field takes a full page URL, pasted straight from the browser's address bar.** No bare IDs, no bare slugs. The Console form now groups secondary inputs into collapsible sections (Limits & performance / Output & debugging) instead of one long list.

#### Removed

- **The single-listing `Listing ID or URL` input** (`similarListingId`). `Similar products` mode now reads the shared `Listing URLs` input instead.
- **Separate wilaya/commune modes.** `Browse a wilaya (state)` and `Browse a commune (city)` merged into one **`Browse a location`** mode — the pasted URL's path (`/state/{slug}` vs `/city/{slug}`) already decides which kind of grid is scraped, so the split only duplicated the choice.

#### Added

- **`Listing URLs` is now the single input for every mode that starts from a listing page.** `Specific listing URLs` scrapes each pasted URL with the full projection; `Similar products` fetches the products from each listing's "Produits similaires" section. Both accept one or more URLs, and both fail with an error naming every invalid entry instead of failing on the first.
- **`Similar products` provenance.** Each similar row records its source listing in the new `similarToId` output field, so results from several source URLs stay easy to group. Null on every other row.
- **Collapsible input sections.** `Limits & performance` and `Output & debugging` group the secondary inputs so the form opens with just the mode picker and its related fields.

#### Changed

- **Renamed inputs.** `Category` (`categorySlug`) → `Category page URL` (`categoryUrl`); `Location` (`locationSlug`) → `Location page URL` (`locationUrl`); `Seller store` (`sellerId`) → `Store page URL` (`sellerUrl`). All three accept full `https://tijelabin.com/…` URLs only.
- **URL-only enforcement.** Bare values are rejected with a validation error instead of being auto-detected: no bare category ids (`15`) or `id/slug` pairs (`15/cars`), no bare location slugs, no bare store hex IDs, no bare listing IDs in `Listing URLs`. Paste the URL from the address bar; that always works.
- **Six run modes:** `search`, `category`, `directUrls`, `location`, `store`, `similar`.

#### Migration

- Saved tasks that pass `similarListingId`, `categorySlug`, `locationSlug`, `sellerId`, `startMode: "state"` or `startMode: "city"` will see a schema-validation warning. Re-pick the mode and paste full URLs: category page URLs into `Category page URL`, `/state/…` or `/city/…` page URLs into `Location page URL` (mode `Browse a location`), store page URLs into `Store page URL`, listing page URLs into `Listing URLs`. Old bare-ID values cannot be converted automatically — open the corresponding page on tijelabin.com and copy the URL from the address bar.

### \[1.1] - 2026-09-02

#### Added

- **`Similar products` mode (`startMode: "similar"`).** Fetches products from the "Produits similaires" section embedded in a listing's detail page. Paste a numeric listing ID (e.g. `8930`) or a full detail URL into the new `Listing ID or URL` input — the Actor extracts the ID and slug automatically. The detail page is fetched via plain HTTP, and the similar-products section is parsed from the HTML. Results are card-shaped rows (title, price, city, image) — the same projection as grid modes.

### \[1.0] - 2026-09-01

#### Added

- Initial release. Six run modes: `search`, `category`, `directUrls`, `state`, `city`, `store`.
- Tijelabin-native output schema — prices extracted as-is (site's `$` label stripped, `currency: "DZD"` hardcoded), seller-entered values preserved.
- Optional sold-listings toggle (`includeSold`).
- Seller-info row for store mode with member-since date and listing counts.
