diff --git a/src/Schuly.Frontend/public/robots.txt b/src/Schuly.Frontend/public/robots.txt new file mode 100644 index 0000000..b971124 --- /dev/null +++ b/src/Schuly.Frontend/public/robots.txt @@ -0,0 +1,6 @@ +User-agent: * +Allow: /login +Allow: /register +Disallow: / + +Sitemap: https://schuly.dev/sitemap.xml diff --git a/src/Schuly.Frontend/src/app/app.ts b/src/Schuly.Frontend/src/app/app.ts index 9c4b330..c709d39 100644 --- a/src/Schuly.Frontend/src/app/app.ts +++ b/src/Schuly.Frontend/src/app/app.ts @@ -1,7 +1,11 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; +import { Component, inject } from '@angular/core'; +import { Meta } from '@angular/platform-browser'; +import { NavigationEnd, Router, RouterOutlet } from '@angular/router'; import { HlmToasterImports } from '@spartan-ng/helm/sonner'; +// Only the sign-in and register pages may show up in search; everything else is behind a login or a one-off link. +const INDEXABLE = new Set(['/login', '/register']); + @Component({ selector: 'app-root', imports: [RouterOutlet, HlmToasterImports], @@ -10,4 +14,13 @@ import { HlmToasterImports } from '@spartan-ng/helm/sonner'; `, }) -export class App {} +export class App { + constructor() { + const meta = inject(Meta); + inject(Router).events.subscribe((e) => { + if (!(e instanceof NavigationEnd)) return; + const path = e.urlAfterRedirects.split(/[?#]/)[0]; + meta.updateTag({ name: 'robots', content: INDEXABLE.has(path) ? 'index, follow' : 'noindex, nofollow' }); + }); + } +} diff --git a/src/Schuly.Frontend/src/index.html b/src/Schuly.Frontend/src/index.html index a026500..c0b559b 100644 --- a/src/Schuly.Frontend/src/index.html +++ b/src/Schuly.Frontend/src/index.html @@ -2,7 +2,8 @@ - Schuly + Schuly – Web-App +