Last active 4 days ago

Ein Service für Angularprojekte als Injectable

mathias revised this gist 4 days ago. Go to revision

No changes

mathias revised this gist 6 days ago. Go to revision

1 file changed, 136 insertions

seo.service.ts(file created)

@@ -0,0 +1,136 @@
1 + import { Injectable, inject } from "@angular/core";
2 + import { Title, Meta } from "@angular/platform-browser";
3 + import { DOCUMENT } from "@angular/common";
4 + import { RendererFactory2 } from "@angular/core";
5 + import { SeoData } from "@core/models/seo.model";
6 +
7 + @Injectable({ providedIn: "root" })
8 + export class SeoService {
9 + private titleService = inject(Title);
10 + private metaService = inject(Meta);
11 + private document = inject(DOCUMENT);
12 + private rendererFactory = inject(RendererFactory2);
13 + private renderer =
14 + this.rendererFactory.createRenderer(null, null);
15 +
16 + // Constants for metadata
17 + private readonly BRAND = "Hurler Webdesign";
18 + private readonly FALLBACK_IMAGE =
19 + 'https://hurler-webdesign.de/assets/og-default.jpg';
20 + private readonly DEFAULT_TYPE = "website";
21 +
22 + /**
23 + * Updates SEO metadata with the provided data.
24 + *
25 + * @param data - The SeoData object containing title, description, type, and image.
26 + * @param canonicalPath - Optional parameter for the canonical URL path.
27 + */
28 + updateMetadata(data: SeoData, canonicalPath?: string) {
29 + const fullTitle = `${data.title} | ${this.BRAND}`;
30 + const url = `https://hurler-webdesign.de${canonicalPath || ""}`;
31 +
32 + // Update title and meta description
33 + this.titleService.setTitle(fullTitle);
34 + this.metaService.updateTag({ name: "description", content: data.description });
35 +
36 + // Open Graph metadata
37 + this.metaService.updateTag({
38 + property: "og:title",
39 + content: fullTitle,
40 + });
41 + this.metaService.updateTag({
42 + property: "og:description",
43 + content: data.description,
44 + });
45 + this.metaService.updateTag({
46 + property: "og:type",
47 + content: data.type || this.DEFAULT_TYPE,
48 + });
49 + this.metaService.updateTag({
50 + property: "og:image",
51 + content: data.image || this.FALLBACK_IMAGE,
52 + });
53 + this.metaService.updateTag({ property: "og:url", content: url });
54 +
55 + // Twitter card metadata
56 + this.metaService.updateTag({
57 + name: "twitter:card",
58 + content: "summary_large_image",
59 + });
60 + this.metaService.updateTag({
61 + name: "twitter:title",
62 + content: fullTitle,
63 + });
64 + this.metaService.updateTag({
65 + name: "twitter:description",
66 + content: data.socialsDescription || data.description,
67 + });
68 + this.metaService.updateTag({ name: "twitter:url", content: url });
69 + this.metaService.updateTag({
70 + name: "twitter:image",
71 + content: data.image || this.FALLBACK_IMAGE,
72 + });
73 +
74 + // Update canonical URL if provided
75 + if (canonicalPath) {
76 + this.updateCanonicalUrl(url);
77 + }
78 +
79 + // Set local business schema.org metadata
80 + this.setLocalBusinessSchema();
81 + }
82 +
83 + /**
84 + * Updates the canonical URL for the given page.
85 + *
86 + * @param url - The new canonical URL.
87 + */
88 + private updateCanonicalUrl(url: string) {
89 + let link: HTMLLinkElement =
90 + this.document.querySelector("link[rel='canonical']") ||
91 + this.renderer.createElement("link");
92 + this.renderer.setAttribute(link, "rel", "canonical");
93 + this.renderer.setAttribute(link, "href", url);
94 + if (!this.document.head.contains(link)) {
95 + this.renderer.appendChild(this.document.head, link);
96 + }
97 + }
98 +
99 + /**
100 + * Sets the local business schema.org JSON-LD script in the head of the document.
101 + */
102 + private setLocalBusinessSchema() {
103 + const oldScript = this.document.getElementById('schema-org-data');
104 + if (oldScript) this.renderer.removeChild(this.document.head, oldScript);
105 +
106 + const schema = {
107 + "@context": "https://schema.org",
108 + "@type": "WebDesignService",
109 + "name": this.BRAND,
110 + "url": "https://hurler-webdesign.de",
111 + "logo": "https://hurler-webdesign.de/assets/logo.png",
112 + "image": "https://hurler-webdesign.de/assets/office.jpg",
113 + "description": "Spezialist für schnelle Webseiten ohne WordPress für Handwerk & Vereine. Wir bieten maßgeschneidertes Webdesign für eine schnelle und sichere Online-Präsenz.",
114 + "address": {
115 + "@type": "PostalAddress",
116 + "streetAddress": "Untermagerbein 30",
117 + "addressLocality": "Mönchsdeggingen",
118 + "postalCode": "86751",
119 + "addressCountry": "DE"
120 + },
121 + "geo": {
122 + "@type": "GeoCoordinates",
123 + "latitude": 48.7506,
124 + "longitude": 10.5773
125 + },
126 + "areaServed": ["Nördlingen", "Donauwörth", "Augsburg", "Bayern"],
127 + "telephone": "+49 171 8084830",
128 + "priceRange": "€€"
129 + };
130 + const script = this.renderer.createElement('script');
131 + script.type = 'application/ld+json';
132 + script.id = 'schema-org-data';
133 + script.text = JSON.stringify(schema);
134 + this.renderer.appendChild(this.document.head, script);
135 + }
136 + }
Newer Older