fix: switch to SSR only

- not actually making use of interactive server
  functionality
- don't need to deal with websocket disconnect
  when server is restarted
- can get necessary functionality using static
  rendering plus executing js on client
  when loaded
- added page script component to handle
  loading collocated scripts for pages that
  also work with enhanced navigation
This commit is contained in:
Stevan Freeborn
2024-04-13 19:09:03 -05:00
parent 279f80fc97
commit 66bef092f3
12 changed files with 179 additions and 50 deletions
+3 -2
View File
@@ -8,13 +8,14 @@
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="Blog.styles.css" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<HeadOutlet @rendermode="InteractiveServer" />
<HeadOutlet />
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<Routes />
<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"></script>
<script src="prism.js"></script>
<script src="_framework/blazor.web.js"></script>
</body>
+2 -2
View File
@@ -2,9 +2,9 @@
<header class="container">
<div class="title-container">
<a href="/">
<NavLink href="/">
<h1>journal</h1>
</a>
</NavLink>
</div>
<div class="author-container">
<span>by</span>
+7 -1
View File
@@ -1,5 +1,4 @@
@inherits LayoutComponentBase
@rendermode InteractiveServer
<div class="container">
<Header />
@@ -13,3 +12,10 @@
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<div id="components-reconnect-modal">
<div>
<h3>Connection lost</h3>
<p>Attempting to reconnect...</p>
</div>
</div>
@@ -32,3 +32,11 @@ main {
right: 0.75rem;
top: 0.5rem;
}
#components-reconnect-modal {
display: none;
position: fixed;
bottom: 0;
right: 0;
padding: 0.5rem;
}
+2 -1
View File
@@ -15,7 +15,8 @@
}
</div>
@code{
@code
{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
+4 -32
View File
@@ -1,5 +1,4 @@
@page "/{slug:nonfile}"
@implements IAsyncDisposable
@inject IPostService PostService
@inject NavigationManager NavigationManager
@inject IJSRuntime JSRuntime
@@ -13,11 +12,12 @@ else
{
<PageTitle>@BlogPost.Title - journal</PageTitle>
<PageScript Src="./Components/Pages/Post.razor.js" />
<HeadContent>
<meta name="description" content="@BlogPost.Lead">
<link rel="stylesheet" href="markdown.css">
<link rel="stylesheet" href="prism.css">
<script src="prism.js"></script>
</HeadContent>
<article>
@@ -31,11 +31,11 @@ else
</article>
}
@code {
@code
{
[Parameter]
public string Slug { get; set; } = string.Empty;
private PostWithContent? BlogPost;
private IJSObjectReference? module;
protected override async Task OnInitializedAsync()
{
@@ -49,32 +49,4 @@ else
BlogPost = post;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./Components/Pages/Post.razor.js");
await module.InvokeVoidAsync("addAnchors");
await module.InvokeVoidAsync("addClipboard");
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
try
{
if (module is not null)
{
await module.DisposeAsync();
}
}
catch (Exception ex) when (ex is JSDisconnectedException)
{
}
catch (Exception ex)
{
Logger.LogError(ex, "Error disposing of the module");
}
}
}
+30 -2
View File
@@ -1,9 +1,37 @@
let initialized = false;
export function onLoad() {
if (initialized) {
return;
}
init();
}
export function onUpdate() {
if (initialized) {
return;
}
init();
}
export function onDispose() {
initialized = false;
}
function init(){
addAnchors();
addClipboard();
Prism.highlightAll();
initialized = true;
}
/**
* @summary Adds anchors to each heading in the post
* so that users can link directly to them.
*/
export function addAnchors() {
function addAnchors() {
const selectors = [
'.markdown-body h2',
'.markdown-body h3',
@@ -21,7 +49,7 @@ export function addAnchors() {
* @summary Adds a button to each code block that
* allows users to copy the code to their clipboard.
*/
export function addClipboard() {
function addClipboard() {
const codeBlocks = document.querySelectorAll('pre');
codeBlocks.forEach((block) => {
+6 -3
View File
@@ -18,19 +18,22 @@
<section role="feed" class="container">
@foreach (var post in Posts)
{
<a href="/@post.Slug">
<NavLink href="@GetLink(post)">
<article>
<h3 title="@post.Title" >@post.Title</h3>
<p class="date">@post.PublishedAt.ToString("MMMM d, yyyy")</p>
<p class="lead">@post.Lead</p>
</article>
</a>
</NavLink>
}
</section>
}
@code {
@code
{
private List<Post>? Posts;
private string GetLink(Post post) => $"/{post.Slug}";
protected override async Task OnInitializedAsync()
{
@@ -0,0 +1,19 @@
@namespace Blog.Components.Utils
@*
custom web-component defined in:
Blog.lib.module.js
Manages loading colocated scripts
for pages and invoking expected
lifecycle methods to support
enhanced page navigation.
*@
<page-script src="@Src"></page-script>
@code
{
[Parameter]
[EditorRequired]
public string Src { get; set; } = default!;
}
+1
View File
@@ -8,3 +8,4 @@
@using Microsoft.JSInterop
@using Blog
@using Blog.Components
@using Blog.Components.Utils