Gå til indhold

Robots.txt generering

Ecreo.Essentials.Seo pakken indeholder værktøjer til generering af robots.txt filer.

Med den dynamiske generering af robots.txt vil vi gerne sikre at test-domæner befaler søgerobotter ikke at følge og indeksere links, ligesom vi gerne vil kunne tilføje løsningsspecifikke regler. Det kunne fx. være der var en mappe af filer på livesitet man ikke vil have indekseret, men man har ikke mulighed for at tilføje robots-meta tagget til filerne specifikt.

Dette er fx. tilfældet med /umbraco og /App_Plugins mapperne i en standard Umbraco installation, som indeholder fx. html-filer. Vi vil helst ikke have at søgerobotterne spilder crawl-tid på at kigge heri, og vi vil slet ikke have de filer indekseret. Men vi kan ikke selv tilføje meta tags til dem, så derfor er de som udgangspunkt disallowed i vores robots.txt fil.

Robots.txt filen, svarer til at lægge en seddel i entréen så indbrudstyven kan se hvor du ikke vil have at han kigger.

Det kan fx. være i skuffen med undertøj. Når indbrudstyven ser dette, kan han hurtigt tænke “det må være der alle værdierne er gemt så”. Så oplysningen om hvor vi gemmer alle vores hemmeligheder, og værdifulde interne ting skal ikke ligge offentligt til skue i en robots.txt fil.

Blokering af sider / ressourcer fra indeksering

Sektion kaldt “Blokering af sider / ressourcer fra indeksering”

Hvis en side reelt er hemmelig, og du helst ikke vil have andre end “særligt udvalgte” til at se siden, så skal den ALDRIG blokeres via robots.txt, men istedet via meta tags i html’en, eller via en response header.

For html du har kontrol over, kan du blot sætte det rette metatag, fx. <meta name="robots" content="noindex">. Har du ikke kontrol over indholdet, eller er filen en partial, hvor der ikke umiddelbart kan indsættes metatags, kan du via middleware tilføje robots-tagget som en response header.

Dette gælder fx. for pdf-filer, som man sjældent vil have indekseret. Her kan du ikke indsætte meta tagget, men i stedet sætte response headeren med navnet X-Robots-Tag og så værdien som du ville sætte i meta robots tagget, fx. noindex.

For at tilføje et middleware til dette, kan du registrere middleware i projektets pipeline:

app.Use(async (context, next) =>
{
if (context.Request.Path.HasValue && context.Request.Path.Value.EndsWith(".pdf"))
{
context.Response.Headers.Add("X-Robots-Tag", "noindex");
}
await next.Invoke();
});

Ovenstående er smart i de tilfælde, fx. ved pdf-filer, hvor du ikke altid ved hvorhenne på disken de ligger. De kan fx. være i /media sammen med alt muligt andet vi gerne vil have indekseret, eller andre steder. Derfor tjekker ovenstående blot om brugeren requester noget der slutter på .pdf, og tilføjer headers efter det.

Er det du vil have “noindex’et” ikke en pdf-fil, tilpasser du blot if-sætningen, så den passer i situationen. Vigtigt, at du ikke blot generelt får sat X-Robots-Tag til noindex. Det vil give os noget af en kattepine, når alle sider på sitet pludselig bliver deindekseret.

Blokering af sider / ressourcer via robots.txt

Sektion kaldt “Blokering af sider / ressourcer via robots.txt”

For ikke-hemmelige sider, fx. det der ligger i /umbraco og /App_Plugins, er det fint blot at have regler til dette i robots.txt.

Seo-pakken tilføjer automatisk disallow regler for disse, men har du en anden sti fx /data du gerne vil have blokeret via robots.txt, så er Seo-pakken forberedt til dette.

Robots.txt genereringen sker dynamisk, hvor den først kigger på requestet til selve robots.txt-filen, herunder hvilket domæne den kaldes på.

Via kode registreres forskellige regelsæt for genereringen af robots.txt regler. Som standard er der en regel der disallower /umbraco og /App_Plugins på produktionsdomænet, samt en regel der disallower alt på test-domæner.

Det færdige robots.txt output caches i runtime cache i 5 minutter pr. effektivt scheme://host. Det betyder at regler, sitemap references og domæneopslag ikke beregnes for hver eneste crawler request.

Hvis du tester med ?host=, bruges den overstyrede host som en del af cache-nøglen. Det gør at /robots.txt?host=example.com og /robots.txt?host=andet-domæne.dk caches hver for sig.

Produktionsdomænet er defineret som det første domæne der er koblet på en node i Umbraco for hvert sprog. Hvis der ikke er koblet domæner på noden (den kigger op i træet, så det er tilstrækkeligt at koble domæner på site-noden), så er der ingen produktionsdomæner, og robots.txt filen vil altid blive genereret som var den på et test-domæne.

Som eksempel har vi et site i Umbraco opsat med følgende domæner:

Domæne Sprog
ecreo.dk dansk
dk.ecreo.com dansk
ecreo.com engelsk
ecreo.azurewebsites.net engelsk
de.ecreo.com tysk

I ovenstående setup er http://ecreo.dk , ecreo.com og de.ecreo.com produktionsdomæner, mens dk.ecreo.com (og øvrige domæner, fx ecreo.azurewebsites.net) testdomæner. Dette er fordi kun det første domæne pr. sprog regnes som produktionsdomæne.

Går man ind på ecreo.dk/robots.txt får man således robots.txt filen for et produktionsdomæne, mens dk.ecreo.com/robots.txt giver robots.txt filen for et testdomæne.

Herved kan vi have testdomæner koblet på en node for at kunne ramme den rigtige sprogvariant, men slippe for at søgerobotterne opfatter dem som live-sites.

Som nævnt ovenfor, sker robots.txt genereringen dynamisk, hvor den løber igennem en række regler for genereringen. Disse er samlet i en collection. Hver enkelt regel er en klasse der implementere IRobotsTxtRule.

Eksempelvis, vil vi gerne have alt i mappen /data blokeret. Derfor implementerer vi følgende regel i vores projekt:

using Ecreo.Essentials.Seo.Interfaces;
using System;
using System.Linq;
using Umbraco.Cms.Core.Services;
namespace MyProject.Seo.Rules
{
public class DisallowDataRobotsTxtRule : IRobotsTxtRule
{
private readonly IDomainService _domainService;
public DisallowDataRobotsTxtRule(IDomainService domainService)
{
_domainService = domainService;
}
public bool IsEnabledInDisallowedDomains() => false;
public bool IsEnabled(Uri requestUri) => true;
public string UserAgent() => "*";
public string[] AllowedPaths() => new string[] { };
public string[] DisallowedPaths() => new string[]
{
"/data/"
};
}
}

IRobotsTxtRule kræver at man implementerer nogle bestemte metoder, beskrevet herunder:

  • IsEnabledInDisallowedDomains() Denne angiver om den aktuelle regel skal bruges på testdomæner. Se definitionen af testdomæner længere oppe. I ovenstående tilfælde gælder reglen for livedomænet, og metoden returnerer derfor false
  • IsEnabled(Uri requestUri) Denne angiver om den aktuelle regel skal bruges på produktionsdomæner. Se definitionen af produktionsdomæner længere oppe. Du får her den aktuelle request URI med, så du kan filtrere yderligere om reglen skal bruge. I dette tilfælde har vi ikke brug for at filtrere yderligere på fx. domæne, så vi returner blot true, for at reglen gælder på alle produktionsdomæner.
  • UserAgent() Denne angiver hvilken User-Agent reglen gælder for. Det kunne fx. være at Googlebot skulle have en regel specifikt for sig, mens andre botter skulle have en anden regel. Her returnerer vi * fordi reglen gælder alle robotter.
  • AllowedPaths() Denne angiver hvilke stier der skal stå som allowed i robots.txt filen. Det er typisk ikke nødvendigt at angive dette. En sti er i udgangspunktet allowed.
  • DisallowedPaths() Denne angiver hvilke siter der skal stå som disallowed i robots.txt filen. Her tilføjer vi /data/ da det er denne sti vi vil have tilføjet som disallowed i vores robots.txt fil.

Nu har vi defineret vores regel, men den skal også tilføjes til den collection som robots.txt generatoren bruger. Det gøres i en IComposer.

using Ecreo.Essentials.Seo.Extensions;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
public class RobotsComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.RobotsTxtRules().Append<MyProject.Seo.Rules.DisallowDataRobotsTxtRule>();
}
}

RobotsTxtRules() er en extension method i Ecreo.Essentials.Seo.Extensions og giver adgang til collectionen af robots.txt rules.

Da robots.txt bliver genereret on-the-fly i forhold til det hostname man kalder den fra, kan det være svært at teste hvordan robots.txt filen virker for specifikke domæner, fx. i produktion. Derfor er der tilføjet en mulighed for at overstyre hvilket hostname robots.txt filen genereres for.

Du kan teste robots.txt for forskellige domæner ved at tilføje en ?host= query parameter til URL’en, f.eks. /robots.txt?host=andet-domæne.dk.