Compare commits

..

No commits in common. "e25722d806c38edf511ae53902ba56c8c4d86b47" and "0bbfc3f4fb707b5eb34452b5f94ef7d24d68f8f6" have entirely different histories.

23 changed files with 3924 additions and 4002 deletions

View File

@ -26,9 +26,7 @@
"Bash(ls:*)", "Bash(ls:*)",
"WebFetch(domain:angular.dev)", "WebFetch(domain:angular.dev)",
"Bash(killall:*)", "Bash(killall:*)",
"Bash(echo:*)", "Bash(echo:*)"
"Bash(npm run build:*)",
"Bash(npx tsc:*)"
] ]
} }
} }

4
.gitattributes vendored
View File

@ -1,4 +0,0 @@
* text=auto eol=lf
*.png binary
*.jpg binary
*.jpeg binary

View File

@ -18,7 +18,7 @@ interface SitemapIndexEntry {
@Injectable() @Injectable()
export class SitemapService { export class SitemapService {
private readonly baseUrl = 'https://www.bizmatch.net'; private readonly baseUrl = 'https://biz-match.com';
private readonly URLS_PER_SITEMAP = 10000; // Google best practice private readonly URLS_PER_SITEMAP = 10000; // Google best practice
constructor(@Inject(PG_CONNECTION) private readonly db: NodePgDatabase<typeof schema>) { } constructor(@Inject(PG_CONNECTION) private readonly db: NodePgDatabase<typeof schema>) { }

View File

@ -1,17 +1,14 @@
import { Routes } from '@angular/router'; import { Routes } from '@angular/router';
// Core components (eagerly loaded - needed for initial navigation)
import { LogoutComponent } from './components/logout/logout.component'; import { LogoutComponent } from './components/logout/logout.component';
import { NotFoundComponent } from './components/not-found/not-found.component'; import { NotFoundComponent } from './components/not-found/not-found.component';
import { TestSsrComponent } from './components/test-ssr/test-ssr.component'; import { TestSsrComponent } from './components/test-ssr/test-ssr.component';
import { EmailAuthorizedComponent } from './components/email-authorized/email-authorized.component'; import { EmailAuthorizedComponent } from './components/email-authorized/email-authorized.component';
import { EmailVerificationComponent } from './components/email-verification/email-verification.component'; import { EmailVerificationComponent } from './components/email-verification/email-verification.component';
import { LoginRegisterComponent } from './components/login-register/login-register.component'; import { LoginRegisterComponent } from './components/login-register/login-register.component';
// Guards
import { AuthGuard } from './guards/auth.guard'; import { AuthGuard } from './guards/auth.guard';
import { ListingCategoryGuard } from './guards/listing-category.guard'; import { ListingCategoryGuard } from './guards/listing-category.guard';
import { UserListComponent } from './pages/admin/user-list/user-list.component';
// Public pages (eagerly loaded - high traffic)
import { DetailsBusinessListingComponent } from './pages/details/details-business-listing/details-business-listing.component'; import { DetailsBusinessListingComponent } from './pages/details/details-business-listing/details-business-listing.component';
import { DetailsCommercialPropertyListingComponent } from './pages/details/details-commercial-property-listing/details-commercial-property-listing.component'; import { DetailsCommercialPropertyListingComponent } from './pages/details/details-commercial-property-listing/details-commercial-property-listing.component';
import { DetailsUserComponent } from './pages/details/details-user/details-user.component'; import { DetailsUserComponent } from './pages/details/details-user/details-user.component';
@ -19,12 +16,16 @@ import { HomeComponent } from './pages/home/home.component';
import { BrokerListingsComponent } from './pages/listings/broker-listings/broker-listings.component'; import { BrokerListingsComponent } from './pages/listings/broker-listings/broker-listings.component';
import { BusinessListingsComponent } from './pages/listings/business-listings/business-listings.component'; import { BusinessListingsComponent } from './pages/listings/business-listings/business-listings.component';
import { CommercialPropertyListingsComponent } from './pages/listings/commercial-property-listings/commercial-property-listings.component'; import { CommercialPropertyListingsComponent } from './pages/listings/commercial-property-listings/commercial-property-listings.component';
import { AccountComponent } from './pages/subscription/account/account.component';
import { EditBusinessListingComponent } from './pages/subscription/edit-business-listing/edit-business-listing.component';
import { EditCommercialPropertyListingComponent } from './pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component';
import { EmailUsComponent } from './pages/subscription/email-us/email-us.component';
import { FavoritesComponent } from './pages/subscription/favorites/favorites.component';
import { MyListingComponent } from './pages/subscription/my-listing/my-listing.component';
import { SuccessComponent } from './pages/success/success.component'; import { SuccessComponent } from './pages/success/success.component';
import { TermsOfUseComponent } from './pages/legal/terms-of-use.component'; import { TermsOfUseComponent } from './pages/legal/terms-of-use.component';
import { PrivacyStatementComponent } from './pages/legal/privacy-statement.component'; import { PrivacyStatementComponent } from './pages/legal/privacy-statement.component';
// Note: Account, Edit, Admin, Favorites, MyListing, and EmailUs components are now lazy-loaded below
export const routes: Routes = [ export const routes: Routes = [
{ {
path: 'test-ssr', path: 'test-ssr',
@ -98,58 +99,58 @@ export const routes: Routes = [
component: DetailsUserComponent, component: DetailsUserComponent,
}, },
// ######### // #########
// User edit (lazy-loaded) // User edit
{ {
path: 'account', path: 'account',
loadComponent: () => import('./pages/subscription/account/account.component').then(m => m.AccountComponent), component: AccountComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
}, },
{ {
path: 'account/:id', path: 'account/:id',
loadComponent: () => import('./pages/subscription/account/account.component').then(m => m.AccountComponent), component: AccountComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
}, },
// ######### // #########
// Create, Update Listings (lazy-loaded) // Create, Update Listings
{ {
path: 'editBusinessListing/:id', path: 'editBusinessListing/:id',
loadComponent: () => import('./pages/subscription/edit-business-listing/edit-business-listing.component').then(m => m.EditBusinessListingComponent), component: EditBusinessListingComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
}, },
{ {
path: 'createBusinessListing', path: 'createBusinessListing',
loadComponent: () => import('./pages/subscription/edit-business-listing/edit-business-listing.component').then(m => m.EditBusinessListingComponent), component: EditBusinessListingComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
}, },
{ {
path: 'editCommercialPropertyListing/:id', path: 'editCommercialPropertyListing/:id',
loadComponent: () => import('./pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component').then(m => m.EditCommercialPropertyListingComponent), component: EditCommercialPropertyListingComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
}, },
{ {
path: 'createCommercialPropertyListing', path: 'createCommercialPropertyListing',
loadComponent: () => import('./pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component').then(m => m.EditCommercialPropertyListingComponent), component: EditCommercialPropertyListingComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
}, },
// ######### // #########
// My Listings (lazy-loaded) // My Listings
{ {
path: 'myListings', path: 'myListings',
loadComponent: () => import('./pages/subscription/my-listing/my-listing.component').then(m => m.MyListingComponent), component: MyListingComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
}, },
// ######### // #########
// My Favorites (lazy-loaded) // My Favorites
{ {
path: 'myFavorites', path: 'myFavorites',
loadComponent: () => import('./pages/subscription/favorites/favorites.component').then(m => m.FavoritesComponent), component: FavoritesComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
}, },
// ######### // #########
// Email Us (lazy-loaded) // EMAil Us
{ {
path: 'emailUs', path: 'emailUs',
loadComponent: () => import('./pages/subscription/email-us/email-us.component').then(m => m.EmailUsComponent), component: EmailUsComponent,
// canActivate: [AuthGuard], // canActivate: [AuthGuard],
}, },
// ######### // #########
@ -173,11 +174,9 @@ export const routes: Routes = [
path: 'success', path: 'success',
component: SuccessComponent, component: SuccessComponent,
}, },
// #########
// Admin Pages (lazy-loaded)
{ {
path: 'admin/users', path: 'admin/users',
loadComponent: () => import('./pages/admin/user-list/user-list.component').then(m => m.UserListComponent), component: UserListComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
}, },
// ######### // #########

View File

@ -10,12 +10,7 @@
<!-- <a routerLink="/login" class="text-primary-500 hover:underline">Login/Register</a> --> <!-- <a routerLink="/login" class="text-primary-500 hover:underline">Login/Register</a> -->
} }
</div> </div>
<button <button (click)="toggleMenu()" class="md:hidden text-neutral-600">
(click)="toggleMenu()"
class="md:hidden text-neutral-600"
aria-label="Open navigation menu"
[attr.aria-expanded]="isMenuOpen"
>
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h16m-7 6h7"></path> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h16m-7 6h7"></path>
</svg> </svg>
@ -31,11 +26,7 @@
<a routerLink="/login" [queryParams]="{ mode: 'login' }" class="text-white text-xl py-2">Log In</a> <a routerLink="/login" [queryParams]="{ mode: 'login' }" class="text-white text-xl py-2">Log In</a>
<a routerLink="/login" [queryParams]="{ mode: 'register' }" class="text-white text-xl py-2">Sign Up</a> <a routerLink="/login" [queryParams]="{ mode: 'register' }" class="text-white text-xl py-2">Sign Up</a>
} }
<button <button (click)="toggleMenu()" class="text-white mt-4">
(click)="toggleMenu()"
class="text-white mt-4"
aria-label="Close navigation menu"
>
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12"></path> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12"></path>
</svg> </svg>
@ -47,41 +38,24 @@
<!-- 1. px-4 für <main> (vorher px-2 sm:px-4) --> <!-- 1. px-4 für <main> (vorher px-2 sm:px-4) -->
<main class="flex flex-col items-center justify-center px-4 w-full flex-grow"> <main class="flex flex-col items-center justify-center px-4 w-full flex-grow">
<div <div
class="relative overflow-hidden pb-12 md:py-20 flex flex-col w-full rounded-xl lg:rounded-2xl md:drop-shadow-custom-md lg:drop-shadow-custom-lg min-h-[calc(100vh_-_20rem)] lg:min-h-[calc(100vh_-_10rem)] max-sm:min-h-[60vh] max-sm:bg-primary-600" class="bg-cover-custom pb-12 md:py-20 flex flex-col w-full rounded-xl lg:rounded-2xl md:drop-shadow-custom-md lg:drop-shadow-custom-lg min-h-[calc(100vh_-_20rem)] lg:min-h-[calc(100vh_-_10rem)] max-sm:bg-contain max-sm:bg-bottom max-sm:bg-no-repeat max-sm:min-h-[60vh] max-sm:bg-primary-600"
> >
<!-- Optimized Background Image --> <div class="flex justify-center w-full">
<picture class="absolute inset-0 w-full h-full z-0 pointer-events-none">
<source srcset="/assets/images/flags_bg.avif" type="image/avif">
<img
width="2500"
height="1285"
fetchpriority="high"
loading="eager"
src="/assets/images/flags_bg.jpg"
alt=""
class="w-full h-full object-cover"
>
</picture>
<!-- Gradient Overlay -->
<div class="absolute inset-0 bg-gradient-to-b from-black/35 via-black/15 to-transparent z-0 pointer-events-none"></div>
<div class="flex justify-center w-full relative z-10">
<!-- 3. Für Mobile: m-2 statt max-w-xs; ab sm: wieder max-width und kein Margin --> <!-- 3. Für Mobile: m-2 statt max-w-xs; ab sm: wieder max-width und kein Margin -->
<div class="w-full m-2 sm:m-0 sm:max-w-md md:max-w-xl lg:max-w-2xl xl:max-w-3xl"> <div class="w-full m-2 sm:m-0 sm:max-w-md md:max-w-xl lg:max-w-2xl xl:max-w-3xl">
<!-- Hero-Container --> <!-- Hero-Container -->
<section class="relative"> <section class="relative">
<!-- Dein Hintergrundbild liegt hier per CSS oder absolutem <img> --> <!-- Dein Hintergrundbild liegt hier per CSS oder absolutem <img> -->
<!-- 1) Overlay: sorgt für Kontrast auf hellem Himmel (Previous overlay removed, using new global overlay) --> <!-- 1) Overlay: sorgt für Kontrast auf hellem Himmel -->
<!-- <div aria-hidden="true" class="pointer-events-none absolute inset-0"></div> --> <div aria-hidden="true" class="pointer-events-none absolute inset-0"></div>
<!-- 2) Textblock --> <!-- 2) Textblock -->
<div class="relative z-10 mx-auto max-w-4xl px-6 sm:px-6 py-4 sm:py-16 text-center text-white"> <div class="relative z-10 mx-auto max-w-4xl px-6 sm:px-6 py-4 sm:py-16 text-center text-white">
<h1 class="text-[1.55rem] sm:text-4xl md:text-5xl lg:text-6xl font-extrabold tracking-tight leading-tight drop-shadow-[0_2px_6px_rgba(0,0,0,0.55)]">Buy & Sell Businesses and Commercial Properties</h1> <h1 class="text-[1.55rem] sm:text-4xl md:text-5xl lg:text-6xl font-extrabold tracking-tight leading-tight drop-shadow-[0_2px_6px_rgba(0,0,0,0.55)]">Buy & Sell Businesses and Commercial Properties</h1>
<p class="mt-3 sm:mt-4 text-base sm:text-lg md:text-xl lg:text-2xl font-medium text-white/90 drop-shadow-[0_1.5px_4px_rgba(0,0,0,0.6)]"> <p class="mt-3 sm:mt-4 text-base sm:text-lg md:text-xl lg:text-2xl font-medium text-white/90 drop-shadow-[0_1.5px_4px_rgba(0,0,0,0.6)]">
Buy profitable businesses for sale or sell your business to qualified buyers. Browse commercial real estate and franchise opportunities across the United States. Find profitable businesses for sale, commercial real estate, and franchise opportunities across the United States
</p> </p>
</div> </div>
</section> </section>
@ -89,66 +63,55 @@
<div class="search-form-container bg-white bg-opacity-80 pb-4 md:pb-6 pt-2 px-3 sm:px-4 md:px-6 rounded-lg shadow-lg w-full" [ngClass]="{ 'pt-6': aiSearch }"> <div class="search-form-container bg-white bg-opacity-80 pb-4 md:pb-6 pt-2 px-3 sm:px-4 md:px-6 rounded-lg shadow-lg w-full" [ngClass]="{ 'pt-6': aiSearch }">
@if(!aiSearch){ @if(!aiSearch){
<div class="text-sm lg:text-base mb-1 text-center text-neutral-500 border-neutral-200 dark:text-neutral-400 dark:border-neutral-700 flex justify-between"> <div class="text-sm lg:text-base mb-1 text-center text-neutral-500 border-neutral-200 dark:text-neutral-400 dark:border-neutral-700 flex justify-between">
<ul class="flex flex-wrap -mb-px w-full" role="tablist"> <ul class="flex flex-wrap -mb-px w-full">
<li class="w-[33%]" role="presentation"> <li class="w-[33%]">
<button <a
type="button"
role="tab"
[attr.aria-selected]="activeTabAction === 'business'"
(click)="changeTab('business')" (click)="changeTab('business')"
[ngClass]=" [ngClass]="
activeTabAction === 'business' activeTabAction === 'business'
? ['text-primary-600', 'border-primary-600', 'active', 'dark:text-primary-500', 'dark:border-primary-500'] ? ['text-primary-600', 'border-primary-600', 'active', 'dark:text-primary-500', 'dark:border-primary-500']
: ['border-transparent', 'hover:text-neutral-600', 'hover:border-neutral-300', 'dark:hover:text-neutral-300'] : ['border-transparent', 'hover:text-neutral-600', 'hover:border-neutral-300', 'dark:hover:text-neutral-300']
" "
class="tab-link w-full hover:cursor-pointer inline-flex items-center justify-center px-3 py-3 md:p-4 border-b-2 rounded-t-lg bg-transparent" class="tab-link hover:cursor-pointer inline-flex items-center justify-center px-1 py-2 md:p-4 border-b-2 rounded-t-lg"
> >
<img src="/assets/images/business_logo.png" alt="" aria-hidden="true" class="tab-icon w-6 h-6 md:w-7 md:h-7 mr-1 md:mr-2 object-contain" width="28" height="28" /> <img src="/assets/images/business_logo.png" alt="Search businesses for sale" class="tab-icon w-6 h-6 md:w-7 md:h-7 mr-1 md:mr-2 object-contain" width="28" height="28" />
<span>Businesses</span> <span>Businesses</span>
</button> </a>
</li> </li>
@if ((numberOfCommercial$ | async) > 0) { @if ((numberOfCommercial$ | async) > 0) {
<li class="w-[33%]" role="presentation"> <li class="w-[33%]">
<button <a
type="button"
role="tab"
[attr.aria-selected]="activeTabAction === 'commercialProperty'"
(click)="changeTab('commercialProperty')" (click)="changeTab('commercialProperty')"
[ngClass]=" [ngClass]="
activeTabAction === 'commercialProperty' activeTabAction === 'commercialProperty'
? ['text-primary-600', 'border-primary-600', 'active', 'dark:text-primary-500', 'dark:border-primary-500'] ? ['text-primary-600', 'border-primary-600', 'active', 'dark:text-primary-500', 'dark:border-primary-500']
: ['border-transparent', 'hover:text-neutral-600', 'hover:border-neutral-300', 'dark:hover:text-neutral-300'] : ['border-transparent', 'hover:text-neutral-600', 'hover:border-neutral-300', 'dark:hover:text-neutral-300']
" "
class="tab-link w-full hover:cursor-pointer inline-flex items-center justify-center px-3 py-3 md:p-4 border-b-2 rounded-t-lg bg-transparent" class="tab-link hover:cursor-pointer inline-flex items-center justify-center px-1 py-2 md:p-4 border-b-2 rounded-t-lg"
> >
<img src="/assets/images/properties_logo.png" alt="" aria-hidden="true" class="tab-icon w-6 h-6 md:w-7 md:h-7 mr-1 md:mr-2 object-contain" width="28" height="28" /> <img src="/assets/images/properties_logo.png" alt="Search commercial properties for sale" class="tab-icon w-6 h-6 md:w-7 md:h-7 mr-1 md:mr-2 object-contain" width="28" height="28" />
<span>Properties</span> <span>Properties</span>
</button> </a>
</li> </li>
} }
<li class="w-[33%]" role="presentation"> <li class="w-[33%]">
<button <a
type="button"
role="tab"
[attr.aria-selected]="activeTabAction === 'broker'"
(click)="changeTab('broker')" (click)="changeTab('broker')"
[ngClass]=" [ngClass]="
activeTabAction === 'broker' activeTabAction === 'broker'
? ['text-primary-600', 'border-primary-600', 'active', 'dark:text-primary-500', 'dark:border-primary-500'] ? ['text-primary-600', 'border-primary-600', 'active', 'dark:text-primary-500', 'dark:border-primary-500']
: ['border-transparent', 'hover:text-neutral-600', 'hover:border-neutral-300', 'dark:hover:text-neutral-300'] : ['border-transparent', 'hover:text-neutral-600', 'hover:border-neutral-300', 'dark:hover:text-neutral-300']
" "
class="tab-link w-full hover:cursor-pointer inline-flex items-center justify-center px-3 py-3 md:p-4 border-b-2 rounded-t-lg bg-transparent" class="tab-link hover:cursor-pointer inline-flex items-center justify-center px-1 py-2 md:p-4 border-b-2 rounded-t-lg"
> >
<img <img
src="/assets/images/icon_professionals.png" src="/assets/images/icon_professionals.png"
alt="" alt="Search business professionals and brokers"
aria-hidden="true" class="tab-icon w-6 h-6 md:w-7 md:h-7 mr-1 md:mr-2 object-contain bg-transparent"
class="tab-icon w-6 h-6 md:w-7 md:h-7 mr-1 md:mr-2 object-contain"
style="mix-blend-mode: darken" style="mix-blend-mode: darken"
width="28" height="28"
/> />
<span>Professionals</span> <span>Professionals</span>
</button> </a>
</li> </li>
</ul> </ul>
</div> </div>
@ -156,11 +119,7 @@
<div class="w-full max-w-3xl mx-auto bg-white rounded-lg flex flex-col md:flex-row md:border md:border-neutral-300"> <div class="w-full max-w-3xl mx-auto bg-white rounded-lg flex flex-col md:flex-row md:border md:border-neutral-300">
<div class="md:flex-none md:w-48 flex-1 md:border-r border-neutral-300 overflow-hidden mb-2 md:mb-0"> <div class="md:flex-none md:w-48 flex-1 md:border-r border-neutral-300 overflow-hidden mb-2 md:mb-0">
<div class="relative max-sm:border border-neutral-300 rounded-md"> <div class="relative max-sm:border border-neutral-300 rounded-md">
<label for="type-filter" class="sr-only">Filter by type</label>
<select <select
id="type-filter"
aria-label="Filter by type"
class="appearance-none bg-transparent w-full py-4 px-4 pr-8 focus:outline-none md:border-none rounded-md md:rounded-none min-h-[52px]" class="appearance-none bg-transparent w-full py-4 px-4 pr-8 focus:outline-none md:border-none rounded-md md:rounded-none min-h-[52px]"
[ngModel]="criteria.types" [ngModel]="criteria.types"
(ngModelChange)="onTypesChange($event)" (ngModelChange)="onTypesChange($event)"
@ -179,7 +138,6 @@
<div class="md:flex-auto md:w-36 flex-grow md:border-r border-neutral-300 mb-2 md:mb-0"> <div class="md:flex-auto md:w-36 flex-grow md:border-r border-neutral-300 mb-2 md:mb-0">
<div class="relative max-sm:border border-neutral-300 rounded-md"> <div class="relative max-sm:border border-neutral-300 rounded-md">
<label for="location-search" class="sr-only">Search by city or state</label>
<ng-select <ng-select
class="custom md:border-none rounded-md md:rounded-none" class="custom md:border-none rounded-md md:rounded-none"
[multiple]="false" [multiple]="false"
@ -193,8 +151,6 @@
(ngModelChange)="setCityOrState($event)" (ngModelChange)="setCityOrState($event)"
placeholder="Enter City or State ..." placeholder="Enter City or State ..."
groupBy="type" groupBy="type"
labelForId="location-search"
aria-label="Search by city or state"
> >
@for (city of cities$ | async; track city.id) { @let state = city.type==='city'?city.content.state:''; @let separator = city.type==='city'?' - ':''; @for (city of cities$ | async; track city.id) { @let state = city.type==='city'?city.content.state:''; @let separator = city.type==='city'?' - ':'';
<ng-option [value]="city">{{ city.content.name }}{{ separator }}{{ state }}</ng-option> <ng-option [value]="city">{{ city.content.name }}{{ separator }}{{ state }}</ng-option>
@ -205,10 +161,7 @@
@if (criteria.radius && !aiSearch){ @if (criteria.radius && !aiSearch){
<div class="md:flex-none md:w-36 flex-1 md:border-r border-neutral-300 mb-2 md:mb-0"> <div class="md:flex-none md:w-36 flex-1 md:border-r border-neutral-300 mb-2 md:mb-0">
<div class="relative max-sm:border border-neutral-300 rounded-md"> <div class="relative max-sm:border border-neutral-300 rounded-md">
<label for="radius-filter" class="sr-only">Filter by radius</label>
<select <select
id="radius-filter"
aria-label="Filter by radius"
class="appearance-none bg-transparent w-full py-4 px-4 pr-8 focus:outline-none md:border-none rounded-md md:rounded-none min-h-[52px]" class="appearance-none bg-transparent w-full py-4 px-4 pr-8 focus:outline-none md:border-none rounded-md md:rounded-none min-h-[52px]"
(ngModelChange)="onRadiusChange($event)" (ngModelChange)="onRadiusChange($event)"
[ngModel]="criteria.radius" [ngModel]="criteria.radius"
@ -227,13 +180,13 @@
} }
<div class="bg-primary-500 hover:bg-primary-600 max-sm:rounded-md search-button"> <div class="bg-primary-500 hover:bg-primary-600 max-sm:rounded-md search-button">
@if( numberOfResults$){ @if( numberOfResults$){
<button aria-label="Search listings" class="w-full h-full text-white font-bold py-2 px-4 md:py-3 md:px-6 focus:outline-none rounded-md md:rounded-none min-h-[52px] flex items-center justify-center gap-2" (click)="search()"> <button class="w-full h-full text-white font-bold py-2 px-4 md:py-3 md:px-6 focus:outline-none rounded-md md:rounded-none min-h-[52px] flex items-center justify-center gap-2" (click)="search()">
<i class="fas fa-search" aria-hidden="true"></i> <i class="fas fa-search"></i>
<span>Search {{ numberOfResults$ | async }}</span> <span>Search {{ numberOfResults$ | async }}</span>
</button> </button>
}@else { }@else {
<button aria-label="Search listings" class="w-full h-full text-white font-bold py-2 px-4 md:py-3 md:px-6 focus:outline-none rounded-md md:rounded-none min-h-[52px] flex items-center justify-center gap-2" (click)="search()"> <button class="w-full h-full text-white font-bold py-2 px-4 md:py-3 md:px-6 focus:outline-none rounded-md md:rounded-none min-h-[52px] flex items-center justify-center gap-2" (click)="search()">
<i class="fas fa-search" aria-hidden="true"></i> <i class="fas fa-search"></i>
<span>Search</span> <span>Search</span>
</button> </button>
} }

View File

@ -1,4 +1,36 @@
.bg-cover-custom {
position: relative;
// Prioritize AVIF format (69KB) over JPG (26MB)
background-image: url('/assets/images/flags_bg.avif');
background-size: cover;
background-position: center;
border-radius: 20px;
// Fallback for browsers that don't support AVIF
@supports not (background-image: url('/assets/images/flags_bg.avif')) {
background-image: url('/assets/images/flags_bg.jpg');
}
// Add gradient overlay for better text contrast
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(180deg, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0.15) 40%, rgba(0, 0, 0, 0.05) 70%, rgba(0, 0, 0, 0) 100%);
border-radius: 20px;
pointer-events: none;
z-index: 1;
}
// Ensure content stays above overlay
> * {
position: relative;
z-index: 2;
}
}
select:not([size]) { select:not([size]) {
background-image: unset; background-image: unset;
} }
@ -237,16 +269,3 @@ header {
} }
} }
} }
// Screen reader only - visually hidden but accessible
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}

View File

@ -1,5 +1,5 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, ViewChild } from '@angular/core'; import { ChangeDetectorRef, Component, ElementRef, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router'; import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { NgSelectModule } from '@ng-select/ng-select'; import { NgSelectModule } from '@ng-select/ng-select';
@ -27,7 +27,6 @@ import { map2User } from '../../utils/utils';
imports: [CommonModule, FormsModule, RouterModule, NgSelectModule, FaqComponent], imports: [CommonModule, FormsModule, RouterModule, NgSelectModule, FaqComponent],
templateUrl: './home.component.html', templateUrl: './home.component.html',
styleUrl: './home.component.scss', styleUrl: './home.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class HomeComponent { export class HomeComponent {
placeholders: string[] = ['Property close to Houston less than 10M', 'Franchise business in Austin price less than 500K']; placeholders: string[] = ['Property close to Houston less than 10M', 'Franchise business in Austin price less than 500K'];
@ -126,15 +125,19 @@ export class HomeComponent {
// Set SEO meta tags for home page // Set SEO meta tags for home page
this.seoService.updateMetaTags({ this.seoService.updateMetaTags({
title: 'BizMatch - Buy & Sell Businesses and Commercial Properties', title: 'BizMatch - Buy & Sell Businesses and Commercial Properties',
description: 'Buy and sell businesses, commercial properties, and franchises. Browse thousands of verified listings across the United States.', description: 'Find profitable businesses for sale, commercial real estate, and franchise opportunities across the United States. Browse thousands of listings from verified sellers and brokers.',
keywords: 'business for sale, businesses for sale, buy business, sell business, commercial property, commercial real estate, franchise opportunities, business broker, business marketplace', keywords: 'business for sale, businesses for sale, buy business, sell business, commercial property, commercial real estate, franchise opportunities, business broker, business marketplace',
type: 'website' type: 'website'
}); });
// Add Organization schema for brand identity // Add Organization schema for brand identity and FAQ schema for AEO
// NOTE: FAQ schema removed because FAQ section is hidden (violates Google's visible content requirement)
// FAQ content is preserved in component for future use when FAQ section is made visible
const organizationSchema = this.seoService.generateOrganizationSchema(); const organizationSchema = this.seoService.generateOrganizationSchema();
const faqSchema = this.seoService.generateFAQPageSchema(
this.faqItems.map(item => ({
question: item.question,
answer: item.answer
}))
);
// Add HowTo schema for buying a business // Add HowTo schema for buying a business
const howToSchema = this.seoService.generateHowToSchema({ const howToSchema = this.seoService.generateHowToSchema({
@ -172,8 +175,7 @@ export class HomeComponent {
// Add SearchBox schema for Sitelinks Search // Add SearchBox schema for Sitelinks Search
const searchBoxSchema = this.seoService.generateSearchBoxSchema(); const searchBoxSchema = this.seoService.generateSearchBoxSchema();
// Inject schemas (FAQ schema excluded - content not visible to users) this.seoService.injectMultipleSchemas([organizationSchema, faqSchema, howToSchema, searchBoxSchema]);
this.seoService.injectMultipleSchemas([organizationSchema, howToSchema, searchBoxSchema]);
// Clear all filters and sort options on initial load // Clear all filters and sort options on initial load
this.filterStateService.resetCriteria('businessListings'); this.filterStateService.resetCriteria('businessListings');

View File

@ -7,7 +7,7 @@
> >
<i class="fas fa-arrow-left text-lg"></i> <i class="fas fa-arrow-left text-lg"></i>
</button> </button>
<h1 class="text-3xl font-bold text-neutral-900 mb-6 pr-14">BizMatch Privacy Policy and Data Protection</h1> <h1 class="text-3xl font-bold text-neutral-900 mb-6 pr-14">Privacy Statement</h1>
<section id="content" role="main"> <section id="content" role="main">
<article class="post page"> <article class="post page">
@ -21,7 +21,7 @@
Policy. Policy.
</p> </p>
<p class="mb-4"> <p class="mb-4">
We may update our Privacy Policy from time to time. Our Privacy Policy was last updated in February 2018 and is effective upon acceptance for new users. By continuing to use our websites or otherwise We may update our Privacy Policy from time to time. Our Privacy Policy was last updated in Febuary 2018 and is effective upon acceptance for new users. By continuing to use our websites or otherwise
continuing to deal with us, you accept this Privacy Policy. continuing to deal with us, you accept this Privacy Policy.
</p> </p>
<p class="font-bold mb-4 mt-6">Collection of personal information</p> <p class="font-bold mb-4 mt-6">Collection of personal information</p>

View File

@ -7,7 +7,7 @@
> >
<i class="fas fa-arrow-left text-lg"></i> <i class="fas fa-arrow-left text-lg"></i>
</button> </button>
<h1 class="text-3xl font-bold text-neutral-900 mb-6 pr-14">BizMatch Terms of Use and User Agreement</h1> <h1 class="text-3xl font-bold text-neutral-900 mb-6 pr-14">Terms of Use</h1>
<section id="content" role="main"> <section id="content" role="main">
<article class="post page"> <article class="post page">

View File

@ -17,9 +17,6 @@
<h1 class="text-3xl md:text-4xl font-bold text-neutral-900 mb-2">Professional Business Brokers & Advisors</h1> <h1 class="text-3xl md:text-4xl font-bold text-neutral-900 mb-2">Professional Business Brokers & Advisors</h1>
<p class="text-lg text-neutral-600">Connect with licensed business brokers, CPAs, attorneys, and other <p class="text-lg text-neutral-600">Connect with licensed business brokers, CPAs, attorneys, and other
professionals across the United States.</p> professionals across the United States.</p>
<div class="mt-4 text-base text-neutral-700 max-w-4xl">
<p>BizMatch connects business buyers and sellers with experienced professionals. Find qualified business brokers to help with your business sale or acquisition. Our platform features verified professionals including business brokers, M&A advisors, CPAs, and attorneys specializing in business transactions across the United States. Whether you're looking to buy or sell a business, our network of professionals can guide you through the process.</p>
</div>
</div> </div>
<!-- Mobile Filter Button --> <!-- Mobile Filter Button -->

View File

@ -1,5 +1,5 @@
import { CommonModule, NgOptimizedImage } from '@angular/common'; import { CommonModule, NgOptimizedImage } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router'; import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { UntilDestroy } from '@ngneat/until-destroy'; import { UntilDestroy } from '@ngneat/until-destroy';
@ -29,7 +29,6 @@ import { assignProperties, resetUserListingCriteria, map2User } from '../../../u
imports: [CommonModule, FormsModule, RouterModule, PaginatorComponent, CustomerSubTypeComponent, BreadcrumbsComponent, SearchModalBrokerComponent], imports: [CommonModule, FormsModule, RouterModule, PaginatorComponent, CustomerSubTypeComponent, BreadcrumbsComponent, SearchModalBrokerComponent],
templateUrl: './broker-listings.component.html', templateUrl: './broker-listings.component.html',
styleUrls: ['./broker-listings.component.scss', '../../pages.scss'], styleUrls: ['./broker-listings.component.scss', '../../pages.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class BrokerListingsComponent implements OnInit, OnDestroy { export class BrokerListingsComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();

View File

@ -14,12 +14,9 @@
<!-- SEO-optimized heading --> <!-- SEO-optimized heading -->
<div class="mb-6"> <div class="mb-6">
<h1 class="text-3xl md:text-4xl font-bold text-neutral-900 mb-2">Businesses for Sale - Find Your Next Business Opportunity</h1> <h1 class="text-3xl md:text-4xl font-bold text-neutral-900 mb-2">Businesses for Sale</h1>
<p class="text-lg text-neutral-600">Discover profitable business opportunities across the United States. Browse <p class="text-lg text-neutral-600">Discover profitable business opportunities across the United States. Browse
verified listings from business owners and brokers.</p> verified listings from business owners and brokers.</p>
<div class="mt-4 text-base text-neutral-700 max-w-4xl">
<p>BizMatch features thousands of businesses for sale across all industries and price ranges. Browse restaurants, retail stores, franchises, service businesses, e-commerce operations, and manufacturing companies. Each listing includes financial details, years established, location information, and seller contact details. Our marketplace connects business buyers with sellers and brokers nationwide, making it easy to find your next business opportunity.</p>
</div>
</div> </div>
<!-- Loading Skeleton --> <!-- Loading Skeleton -->

View File

@ -1,5 +1,5 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router'; import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { UntilDestroy } from '@ngneat/until-destroy'; import { UntilDestroy } from '@ngneat/until-destroy';
@ -31,7 +31,6 @@ import { map2User } from '../../../utils/utils';
imports: [CommonModule, FormsModule, RouterModule, PaginatorComponent, SearchModalComponent, LazyLoadImageDirective, BreadcrumbsComponent], imports: [CommonModule, FormsModule, RouterModule, PaginatorComponent, SearchModalComponent, LazyLoadImageDirective, BreadcrumbsComponent],
templateUrl: './business-listings.component.html', templateUrl: './business-listings.component.html',
styleUrls: ['./business-listings.component.scss', '../../pages.scss'], styleUrls: ['./business-listings.component.scss', '../../pages.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class BusinessListingsComponent implements OnInit, OnDestroy { export class BusinessListingsComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
@ -87,8 +86,8 @@ export class BusinessListingsComponent implements OnInit, OnDestroy {
// Set SEO meta tags for business listings page // Set SEO meta tags for business listings page
this.seoService.updateMetaTags({ this.seoService.updateMetaTags({
title: 'Businesses for Sale | BizMatch', title: 'Businesses for Sale - Find Profitable Business Opportunities | BizMatch',
description: 'Browse thousands of businesses for sale including restaurants, franchises, and retail stores. Verified listings nationwide.', description: 'Browse thousands of businesses for sale across the United States. Find restaurants, franchises, retail stores, and more. Verified listings from business owners and brokers.',
keywords: 'businesses for sale, buy a business, business opportunities, franchise for sale, restaurant for sale, retail business for sale, business broker listings', keywords: 'businesses for sale, buy a business, business opportunities, franchise for sale, restaurant for sale, retail business for sale, business broker listings',
type: 'website' type: 'website'
}); });

View File

@ -16,9 +16,6 @@
<div class="mb-6"> <div class="mb-6">
<h1 class="text-3xl md:text-4xl font-bold text-neutral-900 mb-2">Commercial Properties for Sale</h1> <h1 class="text-3xl md:text-4xl font-bold text-neutral-900 mb-2">Commercial Properties for Sale</h1>
<p class="text-lg text-neutral-600">Find office buildings, retail spaces, warehouses, and industrial properties across the United States. Investment opportunities from verified sellers and commercial real estate brokers.</p> <p class="text-lg text-neutral-600">Find office buildings, retail spaces, warehouses, and industrial properties across the United States. Investment opportunities from verified sellers and commercial real estate brokers.</p>
<div class="mt-4 text-base text-neutral-700 max-w-4xl">
<p>BizMatch showcases commercial real estate listings including office buildings, retail spaces, warehouses, and industrial properties for sale or lease. Browse investment properties across the United States with detailed information on square footage, zoning, pricing, and location. Our platform connects property buyers and investors with sellers and commercial real estate brokers. Find shopping centers, medical buildings, land parcels, and mixed-use developments in your target market.</p>
</div>
</div> </div>
@if(listings?.length > 0) { @if(listings?.length > 0) {

View File

@ -1,5 +1,5 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router'; import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { UntilDestroy } from '@ngneat/until-destroy'; import { UntilDestroy } from '@ngneat/until-destroy';
@ -30,7 +30,6 @@ import { map2User } from '../../../utils/utils';
imports: [CommonModule, FormsModule, RouterModule, PaginatorComponent, SearchModalCommercialComponent, LazyLoadImageDirective, BreadcrumbsComponent], imports: [CommonModule, FormsModule, RouterModule, PaginatorComponent, SearchModalCommercialComponent, LazyLoadImageDirective, BreadcrumbsComponent],
templateUrl: './commercial-property-listings.component.html', templateUrl: './commercial-property-listings.component.html',
styleUrls: ['./commercial-property-listings.component.scss', '../../pages.scss'], styleUrls: ['./commercial-property-listings.component.scss', '../../pages.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class CommercialPropertyListingsComponent implements OnInit, OnDestroy { export class CommercialPropertyListingsComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
@ -84,8 +83,8 @@ export class CommercialPropertyListingsComponent implements OnInit, OnDestroy {
// Set SEO meta tags for commercial property listings page // Set SEO meta tags for commercial property listings page
this.seoService.updateMetaTags({ this.seoService.updateMetaTags({
title: 'Commercial Properties for Sale | BizMatch', title: 'Commercial Properties for Sale - Office, Retail, Industrial Real Estate | BizMatch',
description: 'Browse commercial real estate including offices, retail, warehouses, and industrial properties. Verified investment opportunities.', description: 'Browse commercial real estate listings including office buildings, retail spaces, warehouses, and industrial properties. Investment opportunities from verified sellers and brokers across the United States.',
keywords: 'commercial property for sale, commercial real estate, office building for sale, retail space for sale, warehouse for sale, industrial property, investment property, commercial property listings', keywords: 'commercial property for sale, commercial real estate, office building for sale, retail space for sale, warehouse for sale, industrial property, investment property, commercial property listings',
type: 'website' type: 'website'
}); });

View File

@ -23,9 +23,9 @@ export class SeoService {
private platformId = inject(PLATFORM_ID); private platformId = inject(PLATFORM_ID);
private isBrowser = isPlatformBrowser(this.platformId); private isBrowser = isPlatformBrowser(this.platformId);
private readonly defaultImage = 'https://www.bizmatch.net/assets/images/bizmatch-og-image.jpg'; private readonly defaultImage = 'https://biz-match.com/assets/images/bizmatch-og-image.jpg';
private readonly siteName = 'BizMatch'; private readonly siteName = 'BizMatch';
private readonly baseUrl = 'https://www.bizmatch.net'; private readonly baseUrl = 'https://biz-match.com';
/** /**
* Get the base URL for SEO purposes * Get the base URL for SEO purposes
@ -418,7 +418,6 @@ export class SeoService {
/** /**
* Generate Organization schema for the company * Generate Organization schema for the company
* Enhanced for Knowledge Graph and entity verification
*/ */
generateOrganizationSchema(): object { generateOrganizationSchema(): object {
return { return {
@ -428,47 +427,18 @@ export class SeoService {
'url': this.baseUrl, 'url': this.baseUrl,
'logo': `${this.baseUrl}/assets/images/bizmatch-logo.png`, 'logo': `${this.baseUrl}/assets/images/bizmatch-logo.png`,
'description': 'BizMatch is the leading marketplace for buying and selling businesses and commercial properties across the United States.', 'description': 'BizMatch is the leading marketplace for buying and selling businesses and commercial properties across the United States.',
// Physical address for entity verification
'address': {
'@type': 'PostalAddress',
'streetAddress': '1001 Blucher Street',
'addressLocality': 'Corpus Christi',
'addressRegion': 'TX',
'postalCode': '78401',
'addressCountry': 'US'
},
// Contact information (E.164 format)
'telephone': '+1-800-840-6025',
'email': 'info@bizmatch.net',
// Social media and entity verification
'sameAs': [ 'sameAs': [
'https://www.facebook.com/bizmatch', 'https://www.facebook.com/bizmatch',
'https://www.linkedin.com/company/bizmatch', 'https://www.linkedin.com/company/bizmatch',
'https://twitter.com/bizmatch' 'https://twitter.com/bizmatch'
// Future: Add Wikidata, Crunchbase, Wikipedia when available
], ],
// Enhanced contact point
'contactPoint': { 'contactPoint': {
'@type': 'ContactPoint', '@type': 'ContactPoint',
'telephone': '+1-800-840-6025', 'telephone': '+1-800-BIZ-MATCH',
'contactType': 'Customer Service', 'contactType': 'Customer Service',
'areaServed': 'US', 'areaServed': 'US',
'availableLanguage': 'English', 'availableLanguage': 'English'
'email': 'info@bizmatch.net' }
},
// Business details for Knowledge Graph
'foundingDate': '2020',
'knowsAbout': [
'Business Brokerage',
'Commercial Real Estate',
'Business Valuation',
'Franchise Opportunities'
]
}; };
} }

View File

@ -11,7 +11,7 @@ export interface SitemapUrl {
providedIn: 'root' providedIn: 'root'
}) })
export class SitemapService { export class SitemapService {
private readonly baseUrl = 'https://www.bizmatch.net'; private readonly baseUrl = 'https://biz-match.com';
/** /**
* Generate XML sitemap content * Generate XML sitemap content

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 26 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 2.5 MiB

View File

@ -1,6 +1,6 @@
// Build information, automatically generated by `the_build_script` :zwinkern: // Build information, automatically generated by `the_build_script` :zwinkern:
const build = { const build = {
timestamp: "GER: 03.02.2026 12:44 | TX: 02/03/2026 5:44 AM" timestamp: "GER: 06.01.2026 22:33 | TX: 01/06/2026 3:33 PM"
}; };
export default build; export default build;

View File

@ -1,6 +1,6 @@
# robots.txt for BizMatch - Business Marketplace # robots.txt for BizMatch - Business Marketplace
# https://www.bizmatch.net # https://biz-match.com
# Last updated: 2026-02-03 # Last updated: 2026-01-02
# =========================================== # ===========================================
# Default rules for all crawlers # Default rules for all crawlers
@ -37,9 +37,6 @@ Disallow: /emailUs
Disallow: /api/ Disallow: /api/
Disallow: /bizmatch/ Disallow: /bizmatch/
# Disallow Cloudflare internal paths (prevents 404 errors in crawl reports)
Disallow: /cdn-cgi/
# Disallow search result pages with parameters (to avoid duplicate content) # Disallow search result pages with parameters (to avoid duplicate content)
Disallow: /*?*sortBy= Disallow: /*?*sortBy=
Disallow: /*?*page= Disallow: /*?*page=
@ -130,14 +127,14 @@ Disallow: /
# Sitemap locations # Sitemap locations
# =========================================== # ===========================================
# Main sitemap index (dynamically generated, contains all sub-sitemaps) # Main sitemap index (dynamically generated, contains all sub-sitemaps)
Sitemap: https://www.bizmatch.net/bizmatch/sitemap.xml Sitemap: https://biz-match.com/bizmatch/sitemap.xml
# Individual sitemaps (auto-listed in sitemap index) # Individual sitemaps (auto-listed in sitemap index)
# - https://www.bizmatch.net/bizmatch/sitemap/static.xml # - https://biz-match.com/bizmatch/sitemap/static.xml
# - https://www.bizmatch.net/bizmatch/sitemap/business-1.xml # - https://biz-match.com/bizmatch/sitemap/business-1.xml
# - https://www.bizmatch.net/bizmatch/sitemap/commercial-1.xml # - https://biz-match.com/bizmatch/sitemap/commercial-1.xml
# =========================================== # ===========================================
# Host directive (for Yandex) # Host directive (for Yandex)
# =========================================== # ===========================================
Host: https://www.bizmatch.net Host: https://biz-match.com