From 2ee52523ff8f5643508664c986ca7b28669998ae Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 5 Dec 2025 08:03:20 +0100 Subject: [PATCH] Enhance SEO meta tag handling in generateHTML function by adding support for reading built index.html, updating existing tags, and implementing fallback logic for missing files. --- client/dist/image.png | Bin 0 -> 8175 bytes client/dist/smileys.png | Bin 0 -> 2211 bytes server/routes-seo.js | 103 +++++++++++++++++++++++++++------------- 3 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 client/dist/image.png create mode 100644 client/dist/smileys.png diff --git a/client/dist/image.png b/client/dist/image.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff2d77d739bd538b32d8ca16bf128d50e3aeb67 GIT binary patch literal 8175 zcmeHMc~nzL)=vOMP_SFU1yNr=+YQL_l8~)IWEE@z$f5`$z9cWnlPr(qK>`e|VB?B* ztBqs3ptyi7i13NF8?NBevgqKv^y7jAD zzq+@oE?E>6G0Dl%&5=fT#p@GJmfEio>ksLQo!O)uBd3KwmHl ztr*BTpzH$5RiNwx%4|?R19mkS zr-uxfRu17BREZg2$Q$99z(bfIEv7_CJRM^YdYy(K#c-Tbo#6$^(+D*#11&mjR|PY8 zL7FrYS9i!U0Ib2}ol zp+_~C7lfHeJqjsstrF8)hC?X~6{?kkDxuTq)ftdnj~cZdGD{CNu8~susM=x^)FHqP z1^@=3dJSl{=vvAeYl|9FcD7i`V2<4fwREytphzU{jFuft*7lc8K zfC8!^)R>+@W)PS-C0R~r2qKxIfp9HOGR)rE)sfBQ0K4UwS{xI^K$zY%nimKvDy}-d zCxuC(APy5@Gr4>aJ!}q7%tpi<4#XCSc_Q#flM!j+a9o>aV(^(fCZB;YT}vS5QwK^jp#1}ZRR8?N;a(`Ue55NtM!5?d^z zM3#OAAWTd|K>gnaWKvRRkK_)bKuH z@2I1(=e+y>ecmk|af1XAkcS5bMui0iQU|L7S7S7qXxz-Q-hu;MuuHF@{05e}Pl;hbjt8^Gu3evx&yB&bv014cIX7yS1eMok``M%)_Zn zq1W?YD}IbPGjPG8+5mgc;lC~}4)Kw=Pw`&=GB3Z*;{oGr!oCv;E%#XcnqL=SsTjE3OGj1IBd-8U)e*8U;oaHjQtLppVes4#%749h5u!dY2 zkh-z8c8_03&TZ!Tvg>bJDm8*g+6OMN_2>5mz1gi{nbkXjm(6Y0+`hAa$M~!x&CcxC z@>9i6Lcd7}n9%>=hI#>(lasj7cxHX#WA~E&6W1sT4$_^Sb1H4HommGDlo+%h-c;Rh zvDNVPTPA!fECwlo36G5@<0au@nNGt*&;h~v&EG9D|R+gC}6Ukw}364G{F#ynDBnp`{YOO(R@`cT~Vo;{U zEEqDYkSV@!Jh<`%>hu`I0~Z=LBiMwebKnV%kdI!j5Jv}vSRp{o7gmuZA!f0RMkCY6 zW$N@w79tXfSZof9!(jjoh9N^sq9%scFp7e(U<6?XnI0#oQ~;tdQ7O1P`ob`1hdS)j z5E4lzyw+f40r0^xp#%$IvRN7pt9uUv8JrG4tOotd9)?(O9Ejg+? zgk09ypGecI&C`*~SeP2q096AR75QjL>T=lGgQ7r*YY1~MK=wzPB(CTp>m%E!7V~tv z8v?p_;(nyvF?X{v(2_{RK{{C)WnNg2FHDUumg{7=Tx>2PLMi4g7jPK}D!>>#DI#Y` z*%+6>7IE1!Z$!l7b7kG2!n6hw)ygmm3V<_lfP?a-T&|EOVsI2-MR^Ec$`B!llpzqX zIeY{WN#$&LH;70*4!jaocejdyl2cG34#MH{6b!z%2w1~Lg$z_6lra#6fX9^!6l^)0 zV}_E;#33LJM8R^JuMsRlt28%Igp2*7!hB&4liekW0_h`_qxr(-i+EQV97&4 z7Oc}}m_?R|iosGXHA_{En?nf#SrG^dF)E`%%@;PH>6m4)0G6dm29i*a5BkDZckPhl z|H2h8gbSR&TfxAD2+H8`6>Nrxjfxmt8C$`X@`WguFEX>xiQbXk_$vXAfGgmh=41*Q zXI`lBA8Q*`7_|z3Fa{f8a5z@Nyb&v5EbD|>)Sl5XV;|N(apGfE=(fp#eij+nyue<_ z>f8*ioB@0Pn=k8H{5OYypq@cKiQgW&dg%Hj20lr-$Gdvy`XmNENx8?n{?F)g>`JG= zj~TwO5hP2mf7o3KQY{A}bh?2?V~(O8x@oIlIuP2EVUl3`hx9?c5w2~0AMnczePJfZ z)dF=I>JAQmcUhhkU8mnXv0s~O!MWRuubNg8jeZT+43iZ#8($ur%&ocqY?RG>iF0h& z&FIqQ_vh04yt2DdOUrgS<f@~ux@_weeJQ4v11oaD0uVy-2R_zxMNPP z=O9lUnjPEX8+?gqG*S_Gh1goRbXNeeNHO)^ja|dB@_ifW{o*%GgO~M^_OISp;`nf; zUD1PCVK28AyV>^Mj4z&Y!!G3cpb-rhni`VtXOc@woNlj+>lf8F^*~Mk6U%SL9lA3z zaPVx&JH&HWYhp0}_JTQs3;JD3@;vqE%+ZP4`aYbo4pXg}=25?Iy6m*J=H;ya8M$=* zNwlPN-`*+mxz?wmrTAYkGgp1{p`Y9-w4j_tnevI7#mZ8sgjo|cl(e3 zd92gqgVrskIW=SE8h*Y{&wy4Rldq3zH)!`almzaQuN5{0%K40l+E zGuL?Rd3$Bdi16jFZdO+}Z(Xt>1J5{kFEDM}@kCQ@@pGQaF-=%B;^F7{y;%wQ1&vj; z2PS2@r#2mHyVLk|aN(My;kOn<1cz3H=Q#|XxRza%>rgNJ%1xH>ta|_Rnv<=A2mQWo zW`eeGN&ld}Y`y5Mz05Tsr!W|Ftvh~tSKF!2*)FS~0Ee;b<~eSk7*I8^jQFvcyU>5> z$dT8i7C-Y9` zmJ}7zAXTNlSa9q8i)Y_Cf3P32A-o~J@OtZm2Fn<-Th z->$V8*RRR*K*@meqz@t0A5IpH9(JUvh*?rF#o^61EtbEb7Y|j zQ3ugQv3njZA6mUxneymPO(^lpRK}QDHhmgoCmtmKdG+#R!ThUF|9be36A|uq0rLk| zFUbp!-959?)on@BterWM#LVc&eU6^sCTBd}ef@AgZEotGx9?a_1HPC({MT*Eo;1XU zyIx;h??M|CH}nk3OSEgg+P>t&-j>Gc?R@#U7Uq~*_vvQ?E=+I8jGrRAyyZqnOy6yG zn?<2NTwgG!-AOR=$D-UzU(U>EUEdJ6;rm66)r|1`i+9}aHV9(+=KQcdhaD;@y<}=n zF+Sb!$BT>6ZYPenwq#9GkWRz&qtxs&nR`;KOX;LjTK;L_K4XiHHRn}Z`)G*Pz^4Vp zwZD%v3Vyp+;j!~_M01Q&WYt3Bq3qL7dZQk$bBD&w)K!)jU6?-TM8wvR{W-fC>Pu7e zSH519dav1`aCmU#FDtNhO;9PVHUgRKBvT9x#HMIgT*;5am!>}vUbyq6v-nzQbg#ab zo$|I#cJbfmxOLU*RfUUJCM=k?$hC55dbIH6OW}lRtE=1pvaGsg{%203mcZL{^Tr25 zbptnh?y1>dwY+5Y`U{>lvh`mrwG}^kSHE;6!mgNHrE(}cMIsOXb}=TSwBbVH$@!J( ziC-wf5^NYS~U)D5SNZGx#>O_UYUG`!~WMpN9 z>TSu-FCXk|Q#SIRGOu|s5<{Znz6ctS^lUyc_UovY`#KNyI#yk41@c{gut gvaj%lgWFrbIPdq@`VgL})c@haf+K>;17_v^9c@L~$N&HU literal 0 HcmV?d00001 diff --git a/client/dist/smileys.png b/client/dist/smileys.png new file mode 100644 index 0000000000000000000000000000000000000000..5beb9cd6a97fd38890c242e83aaf1ee4ffcac4ff GIT binary patch literal 2211 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 literal 0 HcmV?d00001 diff --git a/server/routes-seo.js b/server/routes-seo.js index 6eeb85d..6ae0fbc 100644 --- a/server/routes-seo.js +++ b/server/routes-seo.js @@ -1,4 +1,4 @@ -import { readFileSync } from 'fs'; +import { readFileSync, existsSync } from 'fs'; import { join } from 'path'; // SEO-Meta-Daten für verschiedene Routen @@ -26,43 +26,62 @@ const seoData = { }; // HTML-Template für Pre-Rendering -function generateHTML(route, meta) { - const baseHTML = ` - - - - +function generateHTML(route, meta, __dirname) { + // Versuche, die gebaute index.html zu lesen + const distIndexPath = join(__dirname, '../docroot/dist/index.html'); + let baseHTML; - - ${meta.title} - - - - - + if (existsSync(distIndexPath)) { + // Verwende die gebaute index.html (mit korrekten Asset-Pfaden von Vite) + baseHTML = readFileSync(distIndexPath, 'utf-8'); + + // Ersetze Meta-Tags in der gebauten HTML + baseHTML = baseHTML.replace(/.*?<\/title>/, `<title>${meta.title}`); + + // Ersetze oder füge description hinzu + if (baseHTML.includes(']*>/, ``); + } else { + baseHTML = baseHTML.replace('', ` \n`); + } + + // Ersetze oder füge keywords hinzu + if (baseHTML.includes(']*>/, ``); + } else { + baseHTML = baseHTML.replace('', ` \n`); + } + + // Ersetze oder füge Open Graph Tags hinzu + const ogTags = ` - - - - - - - - - - -
- - -`; + `; + + // Entferne alte OG/Twitter/Canonical Tags falls vorhanden + baseHTML = baseHTML.replace(/]*>/g, ''); + baseHTML = baseHTML.replace(/]*>/g, ''); + + // Füge neue Tags vor ein + baseHTML = baseHTML.replace('', `${ogTags}\n`); + + // Füge robots meta hinzu falls nicht vorhanden + if (!baseHTML.includes('', ` \n`); + } + } else { + // Fallback: Gebaute index.html nicht gefunden - verwende SPA-Fallback + console.error('WARNUNG: Gebaute index.html nicht gefunden:', distIndexPath); + return null; + } return baseHTML; } @@ -76,15 +95,35 @@ export function setupSEORoutes(app, __dirname) { // Pre-Rendering für Hauptseite app.get('/', (req, res) => { const meta = seoData['/']; - const html = generateHTML('/', meta); - res.send(html); + const html = generateHTML('/', meta, __dirname); + if (html) { + res.send(html); + } else { + // Fallback: Verwende die gebaute index.html direkt (ohne Meta-Tag-Anpassung) + const distIndexPath = join(__dirname, '../docroot/dist/index.html'); + if (existsSync(distIndexPath)) { + res.sendFile(distIndexPath); + } else { + res.status(500).send('Gebaute index.html nicht gefunden. Bitte führe "npm run build" aus.'); + } + } }); // Pre-Rendering für Partners-Seite app.get('/partners', (req, res) => { const meta = seoData['/partners']; - const html = generateHTML('/partners', meta); - res.send(html); + const html = generateHTML('/partners', meta, __dirname); + if (html) { + res.send(html); + } else { + // Fallback: Verwende die gebaute index.html direkt (ohne Meta-Tag-Anpassung) + const distIndexPath = join(__dirname, '../docroot/dist/index.html'); + if (existsSync(distIndexPath)) { + res.sendFile(distIndexPath); + } else { + res.status(500).send('Gebaute index.html nicht gefunden. Bitte führe "npm run build" aus.'); + } + } }); }