diff --git a/bizmatch/src/app/services/seo.service.ts b/bizmatch/src/app/services/seo.service.ts
index 31f92f4..008ea72 100644
--- a/bizmatch/src/app/services/seo.service.ts
+++ b/bizmatch/src/app/services/seo.service.ts
@@ -1,5 +1,5 @@
-import { Injectable, inject, PLATFORM_ID } from '@angular/core';
-import { isPlatformBrowser } from '@angular/common';
+import { Injectable, inject, PLATFORM_ID, Renderer2, RendererFactory2 } from '@angular/core';
+import { isPlatformBrowser, DOCUMENT } from '@angular/common';
import { Meta, Title } from '@angular/platform-browser';
import { Router } from '@angular/router';
@@ -22,11 +22,17 @@ export class SeoService {
private router = inject(Router);
private platformId = inject(PLATFORM_ID);
private isBrowser = isPlatformBrowser(this.platformId);
+ private document = inject(DOCUMENT);
+ private renderer: Renderer2;
private readonly defaultImage = 'https://www.bizmatch.net/assets/images/bizmatch-og-image.jpg';
private readonly siteName = 'BizMatch';
private readonly baseUrl = 'https://www.bizmatch.net';
+ constructor(rendererFactory: RendererFactory2) {
+ this.renderer = rendererFactory.createRenderer(null, null);
+ }
+
/**
* Get the base URL for SEO purposes
*/
@@ -109,20 +115,18 @@ export class SeoService {
}
/**
- * Update canonical URL
+ * Update canonical URL (SSR-compatible using Renderer2)
*/
private updateCanonicalUrl(url: string): void {
- if (!this.isBrowser) return;
-
- let link: HTMLLinkElement | null = document.querySelector('link[rel="canonical"]');
+ let link: HTMLLinkElement | null = this.document.querySelector('link[rel="canonical"]');
if (link) {
- link.setAttribute('href', url);
+ this.renderer.setAttribute(link, 'href', url);
} else {
- link = document.createElement('link');
- link.setAttribute('rel', 'canonical');
- link.setAttribute('href', url);
- document.head.appendChild(link);
+ link = this.renderer.createElement('link');
+ this.renderer.setAttribute(link, 'rel', 'canonical');
+ this.renderer.setAttribute(link, 'href', url);
+ this.renderer.appendChild(this.document.head, link);
}
}
@@ -269,32 +273,40 @@ export class SeoService {
}
/**
- * Inject JSON-LD structured data into page
+ * Inject JSON-LD structured data into page (SSR-compatible using Renderer2)
*/
injectStructuredData(schema: object): void {
- if (!this.isBrowser) return;
+ // Clear existing schema scripts with the same type
+ this.removeAllSchemas();
- // Remove existing schema script
- const existingScript = document.querySelector('script[type="application/ld+json"]');
- if (existingScript) {
- existingScript.remove();
- }
+ // Create new script element using Renderer2 (works in both SSR and browser)
+ const script = this.renderer.createElement('script');
+ this.renderer.setAttribute(script, 'type', 'application/ld+json');
+ this.renderer.setAttribute(script, 'data-schema', 'true');
- // Add new schema script
- const script = document.createElement('script');
- script.type = 'application/ld+json';
- script.text = JSON.stringify(schema);
- document.head.appendChild(script);
+ // Create text node with schema JSON
+ const schemaText = this.renderer.createText(JSON.stringify(schema));
+ this.renderer.appendChild(script, schemaText);
+
+ // Append to document head
+ this.renderer.appendChild(this.document.head, script);
}
/**
- * Clear all structured data
+ * Remove all schema scripts (internal helper, SSR-compatible)
+ */
+ private removeAllSchemas(): void {
+ const existingScripts = this.document.querySelectorAll('script[data-schema="true"]');
+ existingScripts.forEach(script => {
+ this.renderer.removeChild(this.document.head, script);
+ });
+ }
+
+ /**
+ * Clear all structured data (SSR-compatible)
*/
clearStructuredData(): void {
- if (!this.isBrowser) return;
-
- const scripts = document.querySelectorAll('script[type="application/ld+json"]');
- scripts.forEach(script => script.remove());
+ this.removeAllSchemas();
}
/**
@@ -516,20 +528,21 @@ export class SeoService {
}
/**
- * Inject multiple structured data schemas
+ * Inject multiple structured data schemas (SSR-compatible using Renderer2)
*/
injectMultipleSchemas(schemas: object[]): void {
- if (!this.isBrowser) return;
+ // Clear existing schema scripts
+ this.removeAllSchemas();
- // Remove existing schema scripts
- this.clearStructuredData();
-
- // Add new schema scripts
+ // Add new schema scripts using Renderer2
schemas.forEach(schema => {
- const script = document.createElement('script');
- script.type = 'application/ld+json';
- script.text = JSON.stringify(schema);
- document.head.appendChild(script);
+ const script = this.renderer.createElement('script');
+ this.renderer.setAttribute(script, 'type', 'application/ld+json');
+ this.renderer.setAttribute(script, 'data-schema', 'true');
+
+ const schemaText = this.renderer.createText(JSON.stringify(schema));
+ this.renderer.appendChild(script, schemaText);
+ this.renderer.appendChild(this.document.head, script);
});
}
diff --git a/bizmatch/src/app/utils/logger.ts b/bizmatch/src/app/utils/logger.ts
index f6b2ccd..e6402e4 100644
--- a/bizmatch/src/app/utils/logger.ts
+++ b/bizmatch/src/app/utils/logger.ts
@@ -1,12 +1,25 @@
import { environment } from '../../environments/environment';
-// Development: use browser-bunyan for rich logging
-// Production: use lightweight console wrapper to avoid loading 50KB+ library
-export const createLogger = environment.production
- ? (name: string) => ({
- info: (...args: any[]) => console.log(`[${name}]`, ...args),
- warn: (...args: any[]) => console.warn(`[${name}]`, ...args),
- error: (...args: any[]) => console.error(`[${name}]`, ...args),
- debug: () => {}, // no-op in production
- })
- : require('browser-bunyan').createLogger;
+// Lightweight logger implementation for both dev and production
+// Avoids dynamic require() which causes build issues
+const createLoggerImpl = (name: string) => ({
+ info: (...args: any[]) => {
+ if (!environment.production) {
+ console.log(`[${name}]`, ...args);
+ }
+ },
+ warn: (...args: any[]) => console.warn(`[${name}]`, ...args),
+ error: (...args: any[]) => console.error(`[${name}]`, ...args),
+ debug: (...args: any[]) => {
+ if (!environment.production) {
+ console.debug(`[${name}]`, ...args);
+ }
+ },
+ trace: (...args: any[]) => {
+ if (!environment.production) {
+ console.trace(`[${name}]`, ...args);
+ }
+ }
+});
+
+export const createLogger = createLoggerImpl;
diff --git a/bizmatch/src/build.ts b/bizmatch/src/build.ts
index 4c5c8fc..1a0975a 100644
--- a/bizmatch/src/build.ts
+++ b/bizmatch/src/build.ts
@@ -1,6 +1,6 @@
// Build information, automatically generated by `the_build_script` :zwinkern:
const build = {
- timestamp: "GER: 04.02.2026 21:20 | TX: 02/04/2026 2:20 PM"
+ timestamp: "GER: 05.02.2026 12:45 | TX: 02/05/2026 5:45 AM"
};
export default build;
\ No newline at end of file
diff --git a/bizmatch/src/index.html b/bizmatch/src/index.html
index cbae496..263354f 100644
--- a/bizmatch/src/index.html
+++ b/bizmatch/src/index.html
@@ -61,6 +61,53 @@
+
+
+
+
+