ThemeV2RouteResolver.Resolve is a pure function from path → template + data scope. Paths aretrimmed and lower-cased first. The full table:
` (empty) orhome` — Template:templates/home.fluid— Data scope:Home— Notes: Page title "Home".spaces— Template:templates/spaces.fluid— Data scope:SpaceListing— Notes: Honours?location=,?category=,?attributes=1,2,3.spaces/{slug}— Template:templates/space-detail.fluid— Data scope:SpaceDetail— Notes: Slug is the space UId (GUID); a bare name is accepted as a legacy fallback (prefers the Vacant match, ties broken by Id).units,units/{slug}— Template: asspaces… — Data scope: as above — Notes: Legacy alias — V1 called spaces "units"; the slug is rewritten so old links and pasted embed URLs keep working.locations— Template:templates/locations.fluid— Data scope:Home— Notes: Full locations index.locations/{slug}— Template:templates/location.fluid— Data scope:LocationDetail— Notes: Slug matched against location name (case-insensitive, spaces↔hyphens).locations/{loc}/spaces— Template:templates/spaces.fluid— Data scope:SpaceListing— Notes: Location-scoped listing (LocationSlugset). An unresolvable slug fails closed to an empty listing, never org-wide data.locations/{loc}/spaces/{slug}— Template:templates/space-detail.fluid— Data scope:SpaceDetail— Notes: Detail resolved within that location only.contactorcontact-us— Template:templates/contact.fluid— Data scope:Page(slugcontact) — Notes: Both aliases normalise onto one page key so section settings don't split.attributesorfeatures— Template:templates/attributes.fluid— Data scope:Page(slugattributes) — Notes: Same aliasing; page title "Features".embed/{anything}— Template: inner route's template — Data scope: inner route's scope — Notes: Prefix stripped, inner path resolved normally,IsEmbed = true. Exception: an embedded space listing swaps totemplates/embed-spaces.fluid(self-contained: no breadcrumbs/heading, inline detail view).- anything else — Template:
templates/{slug}.fluid— Data scope:Page— Notes: If no such template exists but a CMS page matches the slug, renders throughtemplates/page.fluid; otherwisetemplates/404.fluid.
?embed=1 on any path is a fallback trigger for embed mode without the /embed/ prefix (usedby the admin preview panel). Embed mode changes the layout choice and the cache key, and setsRequest.IsEmbed / the layout's IsEmbed so templates can adapt.
What each data scope populates
Locations, Categories, Attributes, CmsPages, Menus, Footer, Header and Settingsare populated on every route. On top of that:
Home— Extra data:Spaces= all vacant, active spaces across the org's active non-hidden locations, ordered by Id, capped at 200 (SpaceListingMaxItems).SpaceListing— Extra data: Same asHome, further narrowed by the validated location/category/attribute filters (attribute filters require all listed attributes).SpaceDetail— Extra data:Space= the resolved space;Spaces= a one-element list containing it.LocationDetail— Extra data:Location= the location matched by slug.Page— Extra data:CmsPage= the stored page matching the slug, if any.
Whenever spaces are present, active promotions are matched per space (mirroring the publicsite's baseline rules: same location, same duration type, AppliesTo by entity UId, ascendingpriority) and the winning promotion's label/price fields are stamped onto the space (§4.3).