Skip to content

Commit a89b386

Browse files
hollowaykeanhoJeanShuralyovcorygalyna
committed
Angular: enhanced workspace to be SEO ready
Since this new Angular/ workspace is ready for static site deployment, we can proceed to enhance it for SEO ready. Hence, let's do this. This patch enhances Angular/ workspace to be SEO ready. Co-authored-by: Shuralyov, Jean <jean.shuralyov@proton.me> Co-authored-by: Galyna, Cory <cory.galyna@gmail.com> Co-authored-by: (Holloway) Chew, Kean Ho <me@hollowaykeanho.com> Signed-off-by: (Holloway) Chew, Kean Ho <me@hollowaykeanho.com>
1 parent 50dd906 commit a89b386

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2140
-1086
lines changed

Angular/.ci/clean_unix-any.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ cd "${PROJECT_PATH_ROOT}/${PROJECT_ANGULAR}"
3131

3232
FS_Remove_Silently "dist"
3333
FS_Remove_Silently "node_modules"
34+
FS_Remove_Silently ".angular"
3435

3536
cd "$__current_path"
3637
unset __current_path

Angular/.ci/clean_windows-any.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ $null = Set-Location "${env:PROJECT_PATH_ROOT}\${env:PROJECT_ANGULAR}"
3030

3131
$null = FS-Remove-Silently "dist"
3232
$null = FS-Remove-Silently "node_modules"
33+
$null = FS-Remove-Silently ".angular"
3334

3435
$null = Set-Location "${__current_path}"
3536
$null = Remove-Variable __current_path

Angular/.ci/test_unix-any.sh

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,13 @@ if [ $(OS_Is_Run_Simulated) -eq 0 ]; then
4545
I18N_Simulate_Testing
4646
return 0
4747
else
48-
___old_IFS="$IFS"
49-
while IFS="" read -r ___line || [ -n "$___line" ]; do
50-
___browser="$(type -p chromium)"
51-
if [ ! -z "$___browser" ]; then
52-
break
53-
fi
54-
done << EOF
55-
chromium
56-
google-chrome
57-
brave-browser
58-
EOF
59-
IFS="$___old_IFS" && unset ___old_IFS ___line
60-
61-
if [ "$___browser" = "" ]; then
48+
___browser="$(type -p chromium)"
49+
if [ $(STRINGS_Is_Empty "$___browser") -eq 0 ]; then
6250
I18N_Run_Failed
6351
return 1
6452
fi
6553

66-
CHROME_BIN="$___browser" ./test.sh.ps1
54+
CHROME_BIN="${___browser}" ./test.sh.ps1
6755
if [ $? -ne 0 ]; then
6856
I18N_Run_Failed
6957
return 1

Angular/.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
# (1) Specify your project specific files and directories here. You should #
44
# only touch this section. #
55
################################################################################
6+
services/HestiaFONT_NOTO_EMOJI_COLOR/
7+
services/HestiaFONT_NOTO_SANS/
8+
services/HestiaGUI_ANCHOR/
9+
services/HestiaGUI_BUTTON/
10+
services/HestiaGUI_CORE/
11+
services/HestiaGUI_SOCIAL/
12+
services/HestiaGUI_SOCIAL_BLUESKY/
13+
services/HestiaGUI_ULIST/
14+
services/HestiaSOCIAL/
615

716

817

@@ -19,6 +28,8 @@ assets/manifest.webmanifest
1928
assets/robots.txt
2029
assets/sitemap.xml
2130
assets/sitemaps/
31+
services/app/root.html
32+
services/app/.root.html
2233

2334

2435

Angular/README.md

Lines changed: 67 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ components directories:
1313

1414
1. `contents/` - organize page components with respect to pathing hirarchy.
1515
2. `services/` - where your libraries and service components stays.
16-
3. `services/app/` - where `app-root` and `app-footer` components are located.
17-
4. `services/init/` - where your project init components are located.
16+
3. `services/app/` - where `app-root`, `app-footer`, and `Init.ts` components
17+
are located.
1818
5. `assets/` - any static files located at the root of the site.
1919

20-
The root directory for the workspace is where both `app.ts` and `app.server.ts`
21-
are located.
20+
The root directory for the workspace is where both `main.ts` and
21+
`main.server.ts` are located.
2222

2323
For internationalization (i18n), it is best to keep it as a service component
2424
libraries while keeping the `contents/` directory as the page template. You can
25-
pass the language code using the `app.routes.ts` routing mechanism and have
26-
them rendered accordingly.
25+
definite and pass the language code using the `app.routes.ts` routing mechanism.
26+
Then, the page components can render the specific language accordingly.
2727

2828
To avoid path conflicts, you should always check the `assets/` availability
2929
before creating the content inside `content/` directory.
@@ -51,22 +51,33 @@ $ cd Angular/
5151
$ ./serve.sh.ps1 # for development
5252
$ ./test.sh.ps1 # for test run
5353
$ ./build.sh.ps1 # for build
54+
$ ./watch.sh.ps1 # for watch
5455
```
5556

5657
This is mainly due to Angular does not have any pre-initialization function
57-
where the workspace's critical data files can be updated dynamically
58-
(example: `assets/manifest.webmanifest`, `assets/CNAME`, and etc). To workaround
59-
this, a 2-steps execution is done inside these scripts where the `init.sh.ps1`
60-
(sourced by the all shell scripts) is responsible for building and updating
61-
these critical data files using the server-side-rendering.
58+
to update critical SEO files generations autonomously & dynamically. Affected
59+
files are:
6260

63-
Those are Polygot scripts which means it works on both UNIX and Windows OSes
64-
natively.
61+
* `assets/browserconfig.xml`
62+
* `assets/CNAME`
63+
* `assets/.nojekyll`
64+
* `assets/sitemap.xml`
65+
* `assets/robots.txt`
66+
* `assets/manifest.webmanifest`
67+
* `services/app/root.html`
6568

69+
This includes the `index.html` (`services/app/root.html`) that `angular.json`
70+
depends on. To workaround this issue, a 2-steps execution is done using the
71+
Shell (and PowerShell on Windows) scripts where Stage-1 is to prepare these
72+
criticaly files dynamically while Stage-2 is your designated execution.
6673

74+
Those shell scripts are Polygot in nature so the same script works on both
75+
UNIX and Windows OSes natively.
6776

6877

69-
## Server-Side Rendering (SSR) or Static Site Generation (SSG) First
78+
79+
80+
## Server-Side Rendering (SSR) or Static Site Generation (SSG) Enabled
7081

7182
AutomataCI prioritizes the SSR and SSG (pre-rendering) facilities over other
7283
modes. There is a high chance this project is likely being used to generate
@@ -103,38 +114,42 @@ To set the base URL, update the `baseHref` and `deployUrl` data inside the
103114
`baseHref` is used as the website base URL while `deployUrl` is for the
104115
asset-only base URL.
105116

106-
**DO NOT SEND IN ANY OF THEM VIA COMMAND ARGUMENTS**. The workspace
107-
initialization is only sourcing from `angular.json` data file. Failure can
108-
cause unknown and time-consuming concequences.
117+
> **DO NOT SEND IN ANY OF THEM VIA COMMAND ARGUMENTS**
118+
>
119+
> The workspace initialization is only sourcing from `angular.json` data file.
120+
> Failure can cause unknown and time-consuming concequences.
109121
110122

111123

112124

113125
## Site-Level Metadata
114126

115-
You just need to edit `services/app/metadata.ts` data file that houses the
116-
site-level metadata. Each fields are documented with inline specifications.
127+
You just need to edit `services/app/Metadata.ts` data file that houses the
128+
site-level metadata. Each fields are documented with its inline
129+
specifications.
117130

118131

119132

120133

121134
## PWA Web Manifest
122135

123136
By default, the workspace engine prepares and generates the
124-
`manifest.webmanifest` file dynamically via the 2-steps operation using the
125-
`services/app/metadata.ts` data.
137+
`assets/manifest.webmanifest` file dynamically in the Stage-1 execution.
138+
139+
It generally uses `services/app/Metadata.ts` data for dynamic configurations.
126140

127141

128142

129143

130144
## Site Favicons, Logos, and Screenshots
131145

132146
This workspace defines the favicons, logos, and screenshots metadata in the
133-
`services/app/metadata.ts` data file ("Icons" section). You can supply the
134-
media files in the `assets/` directory.
147+
`services/app/Metadata.ts` data file. You can supply the media files in the
148+
`assets/` directory (e.g. `assets/screenshots/`, `assets/thumbnails/`,
149+
`assets/logos/`).
135150

136-
The default media files are located in `assets/logos/` directory. On the
137-
first run, you can just update these media files to match your project.
151+
If you just want to dive in with site construction, simply override the
152+
existing template files in the `assets/` directory is suffice.
138153

139154

140155

@@ -143,55 +158,31 @@ first run, you can just update these media files to match your project.
143158

144159
By default, AutomataCI setup the default image thumbnails located inside the
145160
`assets/thumbnails/` directory. These images serve as the fall back images
146-
in case the page-level ones failed.
161+
in case the page-level ones failed. These default thumbnails are configurable
162+
in the `services/app/Metadata.ts` file.
147163

148-
In practice, these Open-Graph metadata must be updated at page-level.
164+
The `services/app/root.html` (main template file) is dynamically generated
165+
in Stage-1 execution with the site-level thumbnails meta included.
166+
167+
Currently, Angular updates the meta tags dynamically using `Meta` and `Title`
168+
services from `@angular/platform-browser` library. There is no way to statically
169+
generate/patch the output `index.html` file yet.
149170

150171
Recommended media dimension would be:
151172

152173
1. `1200x630` - horizontal widescreen presentation
153174
2. `1200x1200` - square presentation
154175
3. `480x480` - fallback presentation
155176

156-
You are free to alter the thumbnails located in `services/app/root.html` head
157-
section.
158177

159-
For image, please use:
160178

161-
```
162-
<meta property="og:image" content="/path/to/asset.image" />
163-
<meta property="og:image:type" content="image/FORMAT" />
164-
<meta property="og:image:width" content="WIDTH" />
165-
<meta property="og:image:height" content="HEIGHT" />
166-
<meta property="og:image:alt" content="TITLE" />
167-
```
168179

169-
For video, please use:
170-
171-
```
172-
<meta property="og:video" content="/path/to/asset.video" />
173-
<meta property="og:video:type" content="video/FORMAT" />
174-
<meta property="og:video:width" content="WIDTH" />
175-
<meta property="og:video:height" content="HEIGHT" />
176-
<meta property="og:video:alt" content="CAPTION" />
177-
```
180+
## LD+JSON Search Engine Optimization Schematic Data
178181

179-
For audio, please use:
182+
This feature is pending and under development.
180183

181184
```
182-
<meta property="og:audio" content="/path/to/asset.audio" />
183-
<meta property="og:audio:type" content="audio/FORMAT" />
184-
```
185-
186-
For more technical specification, please refer to the following:
187-
188-
1. https://ogp.me/
189-
190-
191-
192-
193-
## LD+JSON Search Engine Optimization Schematic Data
194-
185+
SPEC:
195186
By default, AutomataCI only setup the default empty tag in the
196187
`services/app/root.html`.
197188
@@ -200,24 +191,30 @@ For more technical specifications, please refer to the following:
200191
201192
1. https://schema.org/docs/full.html
202193
194+
For SEO, the default page **MUST** be the root page since Angular only
195+
pre-render the landing page HTML once and let its Javascript to take over
196+
the others.
197+
```
198+
203199

204200

205201

206202
## Sitemaps & `Robots.txt` Search Engine Optimization (SEO)
207203

208-
By default, the engine generates both the sitemaps and the `robots.txt`
209-
autonomously using the `services/app/metadata.ts` data file via the 2-steps
210-
operation.
204+
By default, the engine generates both the sitemaps (`assets/sitemap.xml` and
205+
the `assets/sitemaps/` directory) and the `assets/robots.txt` autonomously
206+
using the `services/app/Metadata.ts` data file via Stage-1 execution.
211207

212-
The engine is designed to utilize sitemap index for large scale contents.
208+
It uses the sitemap index methodology for large scale contents mapping.
213209

214210

215211

216212

217213
## `browserconfig.xml` fallback configuration
218214

219215
While deemed obselete, this file is generated autonomously for backward
220-
compatibilities and request silencing via the 2-steps operation.
216+
compatibilities and silencing the request using the `services/app/Metadata.ts`
217+
data file via Stage-1 execution.
221218

222219

223220

@@ -226,13 +223,15 @@ compatibilities and request silencing via the 2-steps operation.
226223

227224
Specific to GitHub Pages, the engine generates the `assets/.nojekyll`
228225
configuration file for instructing the facility not to use
229-
[Jekyll](https://jekyllrb.com/) via the 2-steps operation.
226+
[Jekyll](https://jekyllrb.com/) via Stage-1 execution.
230227

231228

232229

233230

234231
## `CNAME` configuration file
235232

236233
Specific to GitHub Pages, the engine generates the `assets/CNAME` config
237-
file based on the `services/app/metadata.ts` data file. This is used by
238-
GitHub Pages to implement custom domain configurations.
234+
file based on the `services/app/Metadata.ts` data file via Stage-1 execution.
235+
236+
This file is used by GitHub Pages to implement custom domain configurations
237+
persistently.

Angular/app.config.server.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
*/
44
import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
55
import { provideServerRendering } from '@angular/platform-server';
6+
67
import { appConfig } from './app.config';
78

89

910

1011

1112
const serverConfig: ApplicationConfig = {
1213
providers: [
13-
provideServerRendering()
14+
provideServerRendering(),
1415
]
1516
};
1617
export const config = mergeApplicationConfig(appConfig, serverConfig);

Angular/app.config.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,43 @@
33
*/
44
import { ApplicationConfig, isDevMode } from '@angular/core';
55
import { provideRouter } from '@angular/router';
6-
7-
import { routes } from './app.routes';
6+
import { APP_BASE_HREF, PlatformLocation } from '@angular/common';
87
import { provideClientHydration } from '@angular/platform-browser';
98
import { provideServiceWorker } from '@angular/service-worker';
109

10+
import { routes } from './app.routes';
11+
12+
13+
14+
15+
export function Parse_URL_Base(target: PlatformLocation): string {
16+
// try parsing from DOM
17+
var output = target.getBaseHrefFromDOM().replace(/\/$/, "");
18+
if (output != '') {
19+
return output;
20+
}
21+
22+
23+
// no choice - construct from protocol, hostname, and port
24+
switch (target.protocol) {
25+
case 'http:':
26+
case 'https:':
27+
output = `${target.protocol}//`;
28+
break;
29+
default:
30+
output = `${target.protocol}`;
31+
break;
32+
}
33+
34+
output += target.hostname;
35+
36+
if (target.port != "") {
37+
output += `:${target.port}`;
38+
}
39+
40+
return output;
41+
}
42+
1143

1244

1345

@@ -18,6 +50,10 @@ export const appConfig: ApplicationConfig = {
1850
provideServiceWorker('ngsw-worker.js', {
1951
enabled: !isDevMode(),
2052
registrationStrategy: 'registerWhenStable:30000'
21-
}),
53+
}), {
54+
provide: APP_BASE_HREF,
55+
useFactory: Parse_URL_Base,
56+
deps: [PlatformLocation],
57+
},
2258
]
2359
};

0 commit comments

Comments
 (0)