diff --git a/.continue/mcpServers/new-mcp-server.yaml b/.continue/mcpServers/new-mcp-server.yaml new file mode 100644 index 0000000..0e32aa6 --- /dev/null +++ b/.continue/mcpServers/new-mcp-server.yaml @@ -0,0 +1,10 @@ +name: New MCP server +version: 0.0.1 +schema: v1 +mcpServers: + - name: New MCP server + command: npx + args: + - -y + - + env: {} diff --git a/package-lock.json b/package-lock.json index 87946ba..767293c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -286,7 +286,6 @@ "version": "21.1.4", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.4.tgz", "integrity": "sha512-ObPTI5gYCB1jGxTRhcqZ6oQVUBFVJ8GH4LksVuAiz0nFX7xxpzARWvlhq943EtnlovVlUd9I8fM3RQqjfGVVAQ==", - "dev": true, "license": "MIT", "dependencies": { "ajv": "8.17.1", @@ -314,7 +313,6 @@ "version": "21.1.4", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.1.4.tgz", "integrity": "sha512-Nqq0ioCUxrbEX+L4KOarETcZZJNnJ1mAJ0ubO4VM91qnn8RBBM9SnQ91590TfC34Szk/wh+3+Uj6KUvTJNuegQ==", - "dev": true, "license": "MIT", "dependencies": { "@angular-devkit/core": "21.1.4", @@ -2046,7 +2044,6 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -3810,7 +3807,6 @@ "version": "21.1.4", "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.1.4.tgz", "integrity": "sha512-I1zdSNzdbrVCWpeE2NsZQmIoa9m0nlw4INgdGIkqUH6FgwvoGKC0RoOxKAmm6HHVJ48FE/sPI13dwAeK89ow5A==", - "dev": true, "license": "MIT", "dependencies": { "@angular-devkit/core": "21.1.4", @@ -4235,7 +4231,6 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -4252,7 +4247,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -4312,7 +4306,6 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -4585,7 +4578,6 @@ "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -4605,7 +4597,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "readdirp": "^5.0.0" @@ -4631,7 +4623,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, "license": "MIT", "dependencies": { "restore-cursor": "^5.0.0" @@ -4647,7 +4638,6 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", "integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==", - "dev": true, "license": "MIT", "engines": { "node": ">=18.20" @@ -5376,14 +5366,12 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, "license": "MIT" }, "node_modules/fast-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "dev": true, "funding": [ { "type": "github", @@ -5514,7 +5502,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -5904,7 +5891,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -5930,7 +5916,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -6057,7 +6042,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, "license": "MIT" }, "node_modules/json-schema-typed": { @@ -6084,7 +6068,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true, "license": "MIT" }, "node_modules/jsonparse": { @@ -6183,7 +6166,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", - "dev": true, "license": "MIT", "dependencies": { "is-unicode-supported": "^2.0.0", @@ -6266,7 +6248,6 @@ "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -6361,7 +6342,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -6878,7 +6858,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, "license": "MIT", "dependencies": { "mimic-function": "^5.0.0" @@ -6894,7 +6873,6 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", - "dev": true, "license": "MIT", "dependencies": { "chalk": "^5.6.2", @@ -7115,7 +7093,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -7273,7 +7250,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 20.19.0" @@ -7294,7 +7271,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7325,7 +7301,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, "license": "MIT", "dependencies": { "onetime": "^7.0.0", @@ -7697,7 +7672,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -7786,7 +7760,6 @@ "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">= 12" @@ -7888,7 +7861,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -7901,7 +7873,6 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.1.tgz", "integrity": "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==", - "dev": true, "license": "MIT", "dependencies": { "get-east-asian-width": "^1.3.0", @@ -7918,7 +7889,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -8689,7 +8659,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" diff --git a/src/app/core/services/seo.service.ts b/src/app/core/services/seo.service.ts index 984a5b1..4844f24 100644 --- a/src/app/core/services/seo.service.ts +++ b/src/app/core/services/seo.service.ts @@ -1,61 +1,87 @@ -import { - Component, - Injectable, - inject, - RendererFactory2, - ViewEncapsulation, - ChangeDetectionStrategy, - signal, - computed } from "@angular/core"; +import { Injectable, inject } from "@angular/core"; import { Title, Meta } from "@angular/platform-browser"; -import { SeoData } from "@core/models/seo.model"; import { DOCUMENT } from "@angular/common"; +import { RendererFactory2 } from "@angular/core"; +import { SeoData } from "@core/models/seo.model"; -@Injectable({providedIn: "root"}) +@Injectable({ providedIn: "root" }) export class SeoService { private titleService = inject(Title); private metaService = inject(Meta); private document = inject(DOCUMENT); private rendererFactory = inject(RendererFactory2); - private renderer = this.rendererFactory.createRenderer(null, null) + private renderer = + this.rendererFactory.createRenderer(null, null); private readonly BRAND = "Hurler Webdesign"; + private readonly FALLBACK_IMAGE = + 'https://hurler-webdesign.de/assets/og-default.jpg'; + private readonly DEFAULT_TYPE = "website"; - updateMetadata(data: SeoData, canonicalPath: string = "") { - const fullTitle = `${data.title} | ${this.BRAND}`; - const url = `https://hurler-webdesign.de${canonicalPath}`; - const fallbackImage = 'https://hurler-webdesign.de/assets/og-default.jpg'; // Falls mal kein Bild da ist + updateMetadata(data: SeoData, canonicalPath?: string) { + const fullTitle = `${data.title} | ${this.BRAND}`; + const url = `https://hurler-webdesign.de${canonicalPath || ""}`; - this.titleService.setTitle(fullTitle); - this.metaService.updateTag({ name: 'description', content: data.description }); + this.titleService.setTitle(fullTitle); + this.metaService.updateTag({ name: "description", content: data.description }); - // Open Graph - this.metaService.updateTag({ property: 'og:title', content: fullTitle }); // Mit Branding - this.metaService.updateTag({ property: 'og:description', content: data.description }); - this.metaService.updateTag({ property: 'og:type', content: data.type || 'website' }); - this.metaService.updateTag({ property: 'og:image', content: data.image || fallbackImage }); - this.metaService.updateTag({ property: 'og:url', content: url }); + // Open Graph + this.metaService.updateTag({ + property: "og:title", + content: fullTitle, + }); + this.metaService.updateTag({ + property: "og:description", + content: data.description, + }); + this.metaService.updateTag({ + property: "og:type", + content: data.type || this.DEFAULT_TYPE, + }); + this.metaService.updateTag({ + property: "og:image", + content: data.image || this.FALLBACK_IMAGE, + }); + this.metaService.updateTag({ property: "og:url", content: url }); - // Twitter - this.metaService.updateTag({ name: 'twitter:card', content: 'summary_large_image' }); // Wichtig für große Bilder! - this.metaService.updateTag({ name: 'twitter:title', content: fullTitle }); - this.metaService.updateTag({ name: 'twitter:description', content: data.description }); - this.metaService.updateTag({ name: 'twitter:url', content: url }); - this.metaService.updateTag({ name: 'twitter:image', content: data.image || fallbackImage }); + // Twitter + this.metaService.updateTag({ + name: "twitter:card", + content: "summary_large_image", + }); + this.metaService.updateTag({ + name: "twitter:title", + content: fullTitle, + }); + this.metaService.updateTag({ + name: "twitter:description", + content: data.socialsDescription || data.description, + }); + this.metaService.updateTag({ name: "twitter:url", content: url }); + this.metaService.updateTag({ + name: "twitter:image", + content: data.image || this.FALLBACK_IMAGE, + }); - this.updateCanonicalUrl(url); - this.setLocalBusinessSchema(); -} + if (canonicalPath) { + this.updateCanonicalUrl(url); + } + + this.setLocalBusinessSchema(); + } private updateCanonicalUrl(url: string) { - let link: HTMLLinkElement = this.document.querySelector("link[rel='canonical']") || this.renderer.createElement('link'); - this.renderer.setAttribute(link, 'rel', 'canonical'); - this.renderer.setAttribute(link, 'href', url); + let link: HTMLLinkElement = + this.document.querySelector("link[rel='canonical']") || + this.renderer.createElement("link"); + this.renderer.setAttribute(link, "rel", "canonical"); + this.renderer.setAttribute(link, "href", url); if (!this.document.head.contains(link)) { this.renderer.appendChild(this.document.head, link); } } + private setLocalBusinessSchema() { const oldScript = this.document.getElementById('schema-org-data'); if (oldScript) this.renderer.removeChild(this.document.head, oldScript);