Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix search engines issue with StreamRendering enabled (#9510) #9511

Conversation

ysmoradi
Copy link
Member

@ysmoradi ysmoradi commented Dec 18, 2024

closes #9510

Summary by CodeRabbit

  • New Features

    • Streamlined script loading for Blazor framework without version-specific conditions.
    • Introduced mechanisms to enhance rendering based on client type, including support for crawler detection.
    • Added new classes to manage rendering behavior for different client types.
  • Bug Fixes

    • Removed outdated conditional compilation directives for improved code clarity.
  • Chores

    • Cleaned up legacy code by removing commented-out sections and unnecessary directives.

@ysmoradi ysmoradi requested a review from msynk December 18, 2024 15:26
Copy link

coderabbitai bot commented Dec 18, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The pull request focuses on enhancing the stream rendering functionality in the Boilerplate project template, specifically addressing crawler compatibility. Changes span multiple files including service-worker.published.js, App.razor, App.razor.cs, and HttpRequestExtensions.cs. The modifications simplify script loading, introduce new container components for stream rendering, and add a method to detect crawler clients by analyzing user agent strings.

Changes

File Change Summary
src/.../service-worker.published.js Removed conditional compilation directives for framework version and project template checks
src/.../App.razor Removed [StreamRendering] attribute, added crawler client detection, simplified Blazor script source
src/.../App.razor.cs Added StreamRenderingEnabledContainer and StreamRenderingDisabledContainer classes
src/.../HttpRequestExtensions.cs Added IsCrawlerClient() method to detect crawler user agents

Assessment against linked issues

Objective Addressed Explanation
Fix stream rendering for crawler clients [#9510]

Poem

🐰 A Blazor tale of rendering might,
Where crawlers dance in streaming light,
No version checks, just pure delight,
Code simplified, a rabbit's bright!
Stream on, little web, take flight! 🌐


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Components/App.razor.cs (1)

29-44: Reduce code duplication in container components

The StreamRenderingEnabledContainer and StreamRenderingDisabledContainer share identical implementation with only the StreamRendering attribute being different.

Consider consolidating into a single component:

 /// <summary>
 /// Streaming pre-rendering enhances user experience (UX) and overall application performance. 
 /// However, it prevents search engines from accessing your pre-rendered dynamic content.
 /// To address this, the conditional logic in App.razor, leveraging <see cref="HttpRequestExtensions.IsCrawlerClient(HttpRequest)"/>, 
 /// disables streaming specifically for search engine crawlers, while maintaining the improved UX and performance for regular users.
 /// </summary>
-[StreamRendering(enabled: true)]
-public class StreamRenderingEnabledContainer : ComponentBase
+public class StreamRenderingContainer : ComponentBase
 {
+    [Parameter] public bool Enabled { get; set; }
     [Parameter] public RenderFragment? ChildContent { get; set; }
 
+    protected override void OnInitialized()
+    {
+        base.OnInitialized();
+        StreamRenderingAttribute.SetEnabled(Enabled);
+    }
+
     protected override void BuildRenderTree(RenderTreeBuilder builder)
     {
         builder.AddContent(0, ChildContent);
     }
 }
-
-/// <summary>
-/// <inheritdoc cref="StreamRenderingEnabledContainer"/>
-/// </summary>
-[StreamRendering(enabled: false)]
-public class StreamRenderingDisabledContainer : ComponentBase
-{
-    [Parameter] public RenderFragment? ChildContent { get; set; }
-
-    protected override void BuildRenderTree(RenderTreeBuilder builder)
-    {
-        builder.AddContent(0, ChildContent);
-    }
-}

Then update the usage in App.razor:

-<StreamRenderingDisabledContainer>
+<StreamRenderingContainer Enabled="false">
     <Routes @rendermode=renderMode />
-</StreamRenderingDisabledContainer>
+</StreamRenderingContainer>

Also applies to: 46-58

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Components/App.razor (2)

68-80: Consider extracting the crawler-based rendering logic

The conditional rendering logic could be encapsulated in a separate component for better maintainability.

Consider creating a CrawlerAwareRenderer component:

+@* CrawlerAwareRenderer.razor *@
+@code {
+    [Parameter] public RenderFragment? ChildContent { get; set; }
+    [Parameter] public RenderMode? RenderMode { get; set; }
+    
+    [CascadingParameter] HttpContext HttpContext { get; set; } = default!;
+}
+
+@if (HttpContext.Request.IsCrawlerClient())
+{
+    <StreamRenderingContainer Enabled="false">
+        @ChildContent
+    </StreamRenderingContainer>
+}
+else
+{
+    <StreamRenderingContainer Enabled="true">
+        @ChildContent
+    </StreamRenderingContainer>
+}

Then simplify the usage in App.razor:

-@if (HttpContext.Request.IsCrawlerClient())
-{
-    <StreamRenderingDisabledContainer>
-        <Routes @rendermode=renderMode />
-    </StreamRenderingDisabledContainer>
-}
-else
-{
-    <StreamRenderingEnabledContainer>
-        <Routes @rendermode=renderMode />
-    </StreamRenderingEnabledContainer>
-}
+<CrawlerAwareRenderer>
+    <Routes @rendermode=renderMode />
+</CrawlerAwareRenderer>

82-84: Elevate version matching comment visibility

The comment about version matching between blazor.web.js and service-worker.published.js is crucial for PWA functionality.

Consider moving this important note to a more visible location, such as:

  1. Add it to the XML documentation of the App component
  2. Create a dedicated README section about PWA setup
  3. Add a warning log during app startup if versions mismatch
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4a4e032 and 9a6f867.

📒 Files selected for processing (4)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Web/wwwroot/service-worker.published.js (0 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Components/App.razor (1 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Components/App.razor.cs (2 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Extensions/HttpRequestExtensions.cs (2 hunks)
💤 Files with no reviewable changes (1)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Web/wwwroot/service-worker.published.js
🔇 Additional comments (1)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Web/Extensions/HttpRequestExtensions.cs (1)

32-39: ⚠️ Potential issue

Add null check for Headers collection

The current implementation might throw NullReferenceException if Headers collection is null.

Add null check:

 private static string GetLoweredUserAgent(HttpRequest request)
 {
+    if (request.Headers == null) return string.Empty;
     var userAgent = request.Headers[HeaderNames.UserAgent].ToString();
 
     if (string.IsNullOrEmpty(userAgent)) return string.Empty;
 
     return userAgent.ToLowerInvariant();
 }

Likely invalid or redundant comment.

@msynk msynk changed the title Fix search engines issue with stream pre-render (#9510) Fix search engines issue with StreamRendering enabled (#9510) Dec 18, 2024
@msynk msynk merged commit 84d075d into bitfoundation:develop Dec 18, 2024
3 checks passed
@ysmoradi ysmoradi deleted the 9510-boilerplate-project-templates-stream-rendering-doesnt-work-with-crawlers-like-google-etc branch December 18, 2024 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Boilerplate project template's Stream rendering doesn't work with crawlers (like google etc)
2 participants