Meniu

Angular 11 Meta tags using NET 5 workarround

Angular 11 Meta tags using NET 5 workarround

How to serve Angular SPA from .NET 5 using the correct meta tags for a specific page.

1.In your startup declare this middleware. What this will do, is to rewrite the index with the correct meta when the path is one that we know it must have different meta.

  app.Use(async (context, next) =>
           {
               await next();
               if (context.Response.StatusCode == 404 &&
                  !Path.HasExtension(context.Request.Path.Value) &&
                  !context.Request.Path.Value.StartsWith("/api/"))
               {
                   var path = context.Request.Path;
                   if (path.Value.Contains("/view-product/"))
                   {
                       try
                       {
                           var idxPath = Path.Combine(env.ContentRootPath, "wwwroot", "index.html");
                           var index = File.ReadAllText(idxPath);
                           index = ViewProductService.GetMeta(index, path.Value);
                           context.Response.StatusCode = 200;
                           await context.Response.WriteAsync(index);
                           return;
                       }
                       catch
                       {
                       }
                   }
                   else if (path.Value.Contains("/news/"))
                   {
                       try
                       {
                           var idxPath = Path.Combine(env.ContentRootPath, "wwwroot", "index.html");
                           var index = File.ReadAllText(idxPath);
                           index = NewsService.GetMeta(index, path.Value);
                           context.Response.StatusCode = 200;
                           await context.Response.WriteAsync(index);
                           return;
                       }
                       catch
                       {
                       }
                   }
                   context.Request.Path = "/index.html";
                   await next();
               }
           });

 2. Each of your services, must rewrite the index with the correct meta. Let's take for example NewsService GetMeta:

   var res = (from x in UOW.DbContext.News
                          where (x.Id_News.ToString() == newsId || x.PermaLink == newsId)
                          select new IndexMetaModel()
                          {
                              OgTitle = settings.DisplayName + " " + x.Subject,
                              OgDescription = x.ShortDescription,
                              OgUrl = Globals.AppUrl + "/news/" + x.PermaLink + "/"
                          }).FirstOrDefault();

Read from db and transform into our meta model. Run the model in the IndexMetaUtil.ReplaceTags.

var resIdx = IndexMetaUtil.ReplaceTags(res, index);

return resIdx;

Bonus:

Use caching for requests:

      if (NewsDomainService.MetaIndex.ContainsKey(path))
           {
               return NewsDomainService.MetaIndex[path];
           }

IdexMetaUtil:

   public static class IndexMetaUtil
   {
       public static string ReplaceTags(IndexMetaModel meta, string index)
       {
           HtmlDocument doc = new HtmlDocument();
           doc.LoadHtml(index);
           var list = doc.DocumentNode.SelectNodes("//meta");
           bool vidFound = false;
           foreach (var node in list)
           {
               string property = node.GetAttributeValue("property", "");
               string value = "";
               switch (property)
               {
                   case "og:title":
                       value = meta.OgTitle;
                       node.SetAttributeValue("content", value);
                       break;
                   case "description":
                   case "og:description":
                       var hd = new HtmlDocument();
                       hd.LoadHtml(meta.OgDescription);
                       value = hd.DocumentNode.InnerText;
                       node.SetAttributeValue("content", value);
                       break;
                   case "og:image":
                       if (!vidFound)
                           value = meta.OgImage;
                       node.SetAttributeValue("content", value);
                       break;
                   case "og:url":
                       value = meta.OgUrl;
                       node.SetAttributeValue("content", value);
                       break;
               }
           }
           return doc.DocumentNode.OuterHtml;
       }
   }

Comentarii:

Autentificati-va pentru a lasa un comentariu.
Nicula Mihaela

:) super