Skip to content

Commit 08e42de

Browse files
authored
Feat: SEO improvements (#250)
Description: Various SEO improvements, based on best SEO practices and Lighthouse suggestions. One suggestion ignored for stylistic reasons. Features: * Added canonical URLs and OpenGraph links * Fonts are now hosted on the server * Removed incorrect aria descriptor on tab bar * Added an aria label to the home button * Updated main theme colours to use `oklch` instead of `hex` * Navbar items are now list item elements inside the navbar list element * Added a background colour to the main HTML page to remove the flashbang
1 parent 1454fd1 commit 08e42de

15 files changed

Lines changed: 110 additions & 62 deletions
22.8 KB
Binary file not shown.

public/fonts/inter-regular.woff2

23.1 KB
Binary file not shown.
18.3 KB
Binary file not shown.
-351 KB
Binary file not shown.
-65.5 KB
Binary file not shown.
-65.6 KB
Binary file not shown.

src/app/app.component.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core';
1+
import { isPlatformBrowser } from '@angular/common';
2+
import { ChangeDetectionStrategy, Component, inject, OnInit, PLATFORM_ID } from '@angular/core';
23
import { Meta } from '@angular/platform-browser';
34
import { ActivatedRoute, Data, NavigationEnd, Router, RouterOutlet } from '@angular/router';
45
import { NavBarComponent } from 'components/nav-bar/nav-bar.component';
56
import { TabBarComponent } from 'components/tab-bar/tab-bar.component';
67
import { of } from 'rxjs';
78
import { filter, map, mergeMap } from 'rxjs/operators';
9+
import { SITE_URL } from 'site';
810

911
const DEFAULT_DESCRIPTION =
1012
"Site dedicated to and maintained by SFU's Computing Science Student Society";
@@ -20,8 +22,10 @@ export class AppComponent implements OnInit {
2022
private router = inject(Router);
2123
private route = inject(ActivatedRoute);
2224
private metaService = inject(Meta);
25+
private platformId = inject(PLATFORM_ID);
2326

2427
ngOnInit(): void {
28+
// Updates the meta description tag and robots tag based on the route's data
2529
this.router.events
2630
.pipe(
2731
filter(event => event instanceof NavigationEnd),
@@ -49,6 +53,18 @@ export class AppComponent implements OnInit {
4953
name: 'description',
5054
content: desc
5155
});
56+
57+
// Canonical URL
58+
if (isPlatformBrowser(this.platformId)) {
59+
const canonicalLink = `${SITE_URL}${this.router.url}`;
60+
let link = document.querySelector("link[rel='canonical']");
61+
if (!link) {
62+
link = document.createElement('link');
63+
link.setAttribute('rel', 'canonical');
64+
document.head.appendChild(link);
65+
}
66+
link.setAttribute('href', canonicalLink);
67+
}
5268
});
5369
}
5470
}

src/app/components/nav-bar/nav-bar.component.html

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<aside class="activity-list" #activityList>
2-
<a class="<activity-list__home></activity-list__home> clickable" routerLink="/"
2+
<a class="activity-list__home clickable" routerLink="/" aria-label="Go to home"
33
><fa-icon class="csss-logo" [icon]="csssIcon" size="2x"
44
/></a>
55
<div
@@ -17,7 +17,7 @@ <h1 class="navbar__heading">SFU CSSS</h1>
1717
<nav>
1818
<ul class="navbar__list">
1919
@for (entry of navEntries(); track entry.key) {
20-
<code-list-item [entry]="entry">
20+
<li code-list-item [entry]="entry">
2121
<button class="nav-entry" type="button" (click)="toggleDirectory(entry.key)">
2222
<fa-icon
2323
class="nav-entry__icon"
@@ -26,37 +26,40 @@ <h1 class="navbar__heading">SFU CSSS</h1>
2626
/>
2727
<span>{{ entry.label }}</span>
2828
</button>
29-
</code-list-item>
29+
</li>
3030
@if (entry.isOpen && entry.children?.length) {
31-
<ul class="navbar__list">
32-
@for (subItem of entry.children; track subItem.key) {
33-
<code-list-item
34-
[entry]="subItem"
35-
[depth]="1"
36-
routerLinkActive="active"
37-
[routerLinkActiveOptions]="{ exact: true }"
38-
>
39-
@if (subItem.route) {
40-
<!-- For routes on the site -->
41-
<a
42-
class="nav-entry"
43-
(click)="navigate(subItem)"
44-
[routerLink]="subItem.route"
45-
[class.clickable]="!subItem.isDisabled"
46-
>
47-
<fa-icon class="nav-entry__icon" [icon]="subItem.icon" [fixedWidth]="true" />
48-
<span>{{ subItem.label }}</span>
49-
</a>
50-
} @else {
51-
<!-- For external links -->
52-
<a class="nav-entry clickable" [href]="subItem.href" target="_blank">
53-
<fa-icon class="nav-entry__icon" [icon]="subItem.icon" [fixedWidth]="true" />
54-
<span>{{ subItem.label }}</span>
55-
</a>
56-
}
57-
</code-list-item>
58-
}
59-
</ul>
31+
<li>
32+
<ul class="navbar__list">
33+
@for (subItem of entry.children; track subItem.key) {
34+
<li
35+
code-list-item
36+
[entry]="subItem"
37+
[depth]="1"
38+
routerLinkActive="active"
39+
[routerLinkActiveOptions]="{ exact: true }"
40+
>
41+
@if (subItem.route) {
42+
<!-- For routes on the site -->
43+
<a
44+
class="nav-entry"
45+
(click)="navigate(subItem)"
46+
[routerLink]="subItem.route"
47+
[class.clickable]="!subItem.isDisabled"
48+
>
49+
<fa-icon class="nav-entry__icon" [icon]="subItem.icon" [fixedWidth]="true" />
50+
<span>{{ subItem.label }}</span>
51+
</a>
52+
} @else {
53+
<!-- For external links -->
54+
<a class="nav-entry clickable" [href]="subItem.href" target="_blank">
55+
<fa-icon class="nav-entry__icon" [icon]="subItem.icon" [fixedWidth]="true" />
56+
<span>{{ subItem.label }}</span>
57+
</a>
58+
}
59+
</li>
60+
}
61+
</ul>
62+
</li>
6063
}
6164
}
6265
</ul>

src/app/components/tab-bar/tab-bar.component.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ export interface TabBarItem {
2424
changeDetection: ChangeDetectionStrategy.OnPush
2525
})
2626
export class TabBarComponent {
27-
@HostBinding('attr.aria-role') get ariaRole(): string {
28-
return 'tablist';
29-
}
30-
3127
@HostBinding('style.height')
3228
get height(): string {
3329
return this.isHidden() ? '0px' : STRUCTURE_MAP['tab-bar-h'];

src/index.html

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,18 @@
1010
content="Site dedicated to and maintained by SFU's Computing Science Student Society"
1111
/>
1212
<link rel="icon" type="image/x-icon" href="static/icons/favicon_colourful.svg" />
13-
<link rel="preconnect" href="https://fonts.googleapis.com" />
14-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
15-
<link
16-
href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Questrial&display=swap"
17-
rel="stylesheet"
18-
/>
13+
<link rel="preload" href="/fonts/inter-regular.woff2" as="font" type="font/woff2" crossorigin />
1914
<meta name="google-site-verification" content="cqWcS1zaOJ2pgBionnStXvsaOEvnyCylR_lZGVaKgyk" />
15+
<meta property="og:title" content="SFU Computing Science Student Society" />
16+
<meta property="og:type" content="website" />
17+
<meta property="og:url" content="https://sfucsss.org" />
18+
<meta property="og:image" content="https://sfucsss.org/static/icons/favicon_colourful.svg" />
19+
<style>
20+
body {
21+
/* This is defined in `src/ui/csss-code/_theme.scss` as `$bg1` and `$bg3` */
22+
background-color: oklch(17.76% 0 0);
23+
}
24+
</style>
2025
</head>
2126

2227
<body>

0 commit comments

Comments
 (0)