Skip to main content

Real estate and geo

Property titles repeat constantly — every city has a "Loft am Park" — and the location is the part a visitor actually navigates by.

#[Polyslug(source: 'title', scope: 'city_id')] // identical listing titles are fine across cities
class Property extends Model implements Sluggable
{
use HasPolyslug;

public function polyslugParent(): ?Sluggable
{
return $this->neighborhood; // /berlin/mitte/loft-am-park_x7Q — the path is composed from the location
}
}
  • scope: 'city_id' keeps uniqueness per city, so the same title in Hamburg does not become loft-am-park-2.
  • polyslugParent() composes the neighborhood (and its own parent, the city) into the path, computed on read. Renaming a neighborhood changes every listing URL beneath it and 301s the old ones — with no cascade to run.

The parent chain is depth-bounded, so a mis-entered geography that points at itself stops rather than looping.

Sold listings

A sold property should not be a soft-404. Either return 410 with polyslugIsGone(), or 301 to a comparable listing with polyslugSupersededBy() — and use polyslugIsRoutable() to drop it from the sitemap either way.

See also