Skip to content

Commit a9e04cc

Browse files
committed
Enhance SEO and meta tag management
- Added `site.js` script reference in `App.razor` for managing meta tags and document title. - Updated page title in `PluginsDetails.razor` to include plugin type and version. - Introduced dynamic rendering of meta tags based on plugin data to improve SEO and social media sharing. - Reformatted plugin description display for consistency. - Added parameters in `MetaTags.razor` for dynamic SEO-related meta tags, including Open Graph and Twitter tags. - Implemented `OnAfterRenderAsync` method to set meta tags and title after component rendering. - Created `metaManager` JavaScript object in `site.js` for centralized meta tag management. #42
1 parent 074b078 commit a9e04cc

4 files changed

Lines changed: 86 additions & 6 deletions

File tree

src/FlowSynx.Pluginregistry/Components/App.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<script src="@Assets["lib/bootstrap/dist/js/bootstrap.bundle.min.js"]"></script>
2020
<script src="_framework/blazor.web.js"></script>
2121
<script src="@Assets["lib/clipboard.js"]"></script>
22+
<script src="@Assets["lib/site.js"]"></script>
2223
</body>
2324

2425
</html>

src/FlowSynx.Pluginregistry/Components/Pages/Plugins/PluginsDetails.razor

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,20 @@
1111
@inject NavigationManager Navigation
1212
@inject IStatsApiService Stats
1313

14-
<PageTitle>Plugin details</PageTitle>
14+
<PageTitle>Plugin details for @Type version @Version</PageTitle>
15+
16+
@if (plugin != null && plugin.Succeeded)
17+
{
18+
<MetaTags Title="@($"{Type} v{Version}")"
19+
Description="@plugin.Data.Description"
20+
Author="@string.Join(",", plugin.Data.Owners)"
21+
Keywords="@string.Join(",", plugin.Data.Tags)"
22+
OgTitle="@($"{Type} v{Version}")"
23+
OgDescription="@plugin.Data.Description"
24+
OgUrl="@plugin.Data.RepositoryUrl"
25+
TwitterSite="@plugin.Data.RepositoryUrl"
26+
TwitterCreator="@string.Join(",", plugin.Data.Owners)" />
27+
}
1528

1629
<div class="container p-5">
1730
<div class="row">
@@ -47,7 +60,7 @@
4760
<div class="position-relative mb-2">
4861
<CodeCopy CodeToCopy="@jsonCodeBlock" />
4962
<pre class="plugin-code-block border bg-light"><code>@jsonCodeBlock</code>
50-
</pre>
63+
</pre>
5164
</div>
5265

5366
<p class="p-2 border">@plugin.Data.Description</p>
@@ -93,10 +106,10 @@
93106
</div>
94107
@if (!string.IsNullOrEmpty(plugin.Data.ProjectUrl))
95108
{
96-
<div class="mb-3">
97-
<i class="bi bi-globe text-secondary"></i>
98-
<a href="@plugin.Data.ProjectUrl" target="_blank">Project Website</a>
99-
</div>
109+
<div class="mb-3">
110+
<i class="bi bi-globe text-secondary"></i>
111+
<a href="@plugin.Data.ProjectUrl" target="_blank">Project Website</a>
112+
</div>
100113
}
101114
@if (!string.IsNullOrEmpty(plugin.Data.RepositoryUrl))
102115
{
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
@inject IJSRuntime JS
2+
3+
@code {
4+
// Standard SEO
5+
[Parameter] public string? Title { get; set; }
6+
[Parameter] public string? Description { get; set; }
7+
[Parameter] public string? Author { get; set; }
8+
[Parameter] public string? Keywords { get; set; }
9+
10+
// Open Graph
11+
[Parameter] public string? OgTitle { get; set; }
12+
[Parameter] public string? OgDescription { get; set; }
13+
[Parameter] public string? OgImage { get; set; }
14+
[Parameter] public string? OgUrl { get; set; }
15+
[Parameter] public string? OgType { get; set; } = "website";
16+
17+
// Twitter
18+
[Parameter] public string? TwitterSite { get; set; }
19+
[Parameter] public string? TwitterCreator { get; set; }
20+
21+
protected override async Task OnAfterRenderAsync(bool firstRender)
22+
{
23+
if (!firstRender) return;
24+
25+
// Standard SEO
26+
await JS.InvokeVoidAsync("metaManager.setTitle", Title);
27+
await JS.InvokeVoidAsync("metaManager.setMeta", "description", Description);
28+
await JS.InvokeVoidAsync("metaManager.setMeta", "author", Author);
29+
await JS.InvokeVoidAsync("metaManager.setMeta", "keywords", Keywords);
30+
31+
// Open Graph
32+
await JS.InvokeVoidAsync("metaManager.setMeta", "og:title", OgTitle ?? Title);
33+
await JS.InvokeVoidAsync("metaManager.setMeta", "og:description", OgDescription ?? Description);
34+
await JS.InvokeVoidAsync("metaManager.setMeta", "og:image", OgImage);
35+
await JS.InvokeVoidAsync("metaManager.setMeta", "og:url", OgUrl);
36+
await JS.InvokeVoidAsync("metaManager.setMeta", "og:type", OgType);
37+
38+
// Twitter
39+
await JS.InvokeVoidAsync("metaManager.setMeta", "twitter:site", TwitterSite);
40+
await JS.InvokeVoidAsync("metaManager.setMeta", "twitter:creator", TwitterCreator);
41+
await JS.InvokeVoidAsync("metaManager.setMeta", "twitter:title", OgTitle ?? Title);
42+
await JS.InvokeVoidAsync("metaManager.setMeta", "twitter:description", OgDescription ?? Description);
43+
await JS.InvokeVoidAsync("metaManager.setMeta", "twitter:image", OgImage);
44+
}
45+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
window.metaManager = {
2+
setMeta: (name, content) => {
3+
if (!content) return;
4+
let element = document.querySelector(`meta[name='${name}']`) || document.querySelector(`meta[property='${name}']`);
5+
if (element) {
6+
element.setAttribute("content", content);
7+
} else {
8+
element = document.createElement("meta");
9+
if (name.startsWith("og:") || name.startsWith("twitter:")) {
10+
element.setAttribute("property", name); // Open Graph uses property
11+
} else {
12+
element.setAttribute("name", name);
13+
}
14+
element.setAttribute("content", content);
15+
document.head.appendChild(element);
16+
}
17+
},
18+
setTitle: (title) => {
19+
if (title) document.title = title;
20+
}
21+
};

0 commit comments

Comments
 (0)