Skip to content

Commit

Permalink
Preloaded and Angular Routed
Browse files Browse the repository at this point in the history
This is a solution to using the Angular Router to avoid client side requests
  • Loading branch information
AaronAgility committed Nov 7, 2024
1 parent aa6c5f3 commit 628d849
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 57 deletions.
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@
/out-tsc
/.angular
/bazel-out
prerender-routes.js

# environment files
/src/environments/environment.prod.ts
/src/environments/environment.ts
/src/environments
content.json
pages.json
agility-routes.txt

#agility prerendering
prerender-routes.js
prerender-pages.js
prerender-content.js
agility-routes.txt
pages.json
content.json

# dependencies
/node_modules

Expand Down
4 changes: 2 additions & 2 deletions dotenv.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const path = require('path');

const development = `
export const environment = {
AGILITY_PREVIEW: true,
AGILITY_PREVIEW: '${process.env.AGILITY_PREVIEW}',
AGILITY_GUID: '${process.env.AGILITY_GUID}',
AGILITY_API_FETCH_KEY: '${process.env.AGILITY_API_FETCH_KEY}',
AGILITY_API_PREVIEW_KEY: '${process.env.AGILITY_API_PREVIEW_KEY}',
Expand All @@ -14,7 +14,7 @@ export const environment = {
`;
const production = `
export const environment = {
AGILITY_PREVIEW: false,
AGILITY_PREVIEW: '${process.env.AGILITY_PREVIEW}',
AGILITY_GUID: '${process.env.AGILITY_GUID}',
AGILITY_API_FETCH_KEY: '${process.env.AGILITY_API_FETCH_KEY}',
AGILITY_API_PREVIEW_KEY: '${process.env.AGILITY_API_PREVIEW_KEY}',
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
"test": "ng test",
"envinit": "node dotenv.config.js",
"dev": "npm run envinit && ng serve",
"build": "npm run envinit && npm run prerender:routes && ng build --configuration production",
"build": "npm run agility-init && ng build --configuration production",
"start": "ng serve --configuration production",
"prerender:routes": "tsc prerender-routes.ts && node prerender-routes.js"

"agility-init": "npm run envinit && npm run prerender:routes && npm run prerender:pages && npm run prerender:content",
"prerender:routes": "tsc prerender-routes.ts && node prerender-routes.js",
"prerender:pages": "tsc prerender-pages.ts && node prerender-pages.js",
"prerender:content": "tsc prerender-content.ts && node prerender-content.js"
},
"private": true,
"dependencies": {
Expand Down
48 changes: 48 additions & 0 deletions prerender-content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { getApi } from '@agility/content-fetch';
import * as fs from 'fs';
import * as path from 'path';
import * as dotenv from 'dotenv';

dotenv.config();


const client = getApi({
guid: process.env['AGILITY_GUID'],
apiKey: process.env['AGILITY_API_FETCH_KEY'],
isPreview: Boolean(process.env['AGILITY_PREVIEW']),
});

const contentListsToPreRender = ['posts', 'categories'];

async function prerenderPages() {

let allContentListsData: { [key: string]: any } = {};

for(const contentList of contentListsToPreRender) {

// Fetch the content list
const list = await client.getContentList({
referenceName: contentList,
languageCode: process.env['AGILITY_LOCALE'],
locale: process.env['AGILITY_LOCALE'],
});

// Add the list to the allContentListsData object
allContentListsData[contentList] = list;

console.log(`Fetched content list: ${contentList}`);
}

// Define the JSON output path for the aggregated data
const aggregatedJsonOutputPath = path.join(__dirname, 'src', 'app', 'agility', 'data', 'content.json');

// Ensure the directory exists
fs.mkdirSync(path.dirname(aggregatedJsonOutputPath), { recursive: true });

// Write the aggregated data to the JSON file
fs.writeFileSync(aggregatedJsonOutputPath, JSON.stringify(allContentListsData, null, 2), 'utf8');


}

prerenderPages();
63 changes: 63 additions & 0 deletions prerender-pages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { getApi } from '@agility/content-fetch';
import * as fs from 'fs';
import * as path from 'path';
import * as dotenv from 'dotenv';

dotenv.config();

const apiKey = process.env['AGILITY_API_FETCH_KEY'];
const guid = process.env['AGILITY_GUID'];
const locale = process.env['AGILITY_LOCALE'] || 'en-use';
const channel = process.env['AGILITY_WEBSITE'] || 'website';

const client = getApi({
guid,
apiKey,
isPreview: false
});

async function prerenderPages() {
// Fetch the sitemap
const sitemap = await client.getSitemapFlat({ languageCode: locale, channelName: channel, locale });

// Object to hold all page data
let allPageData: { [key: string]: { page: any, dynamicPageItem: any } } = {};

for (const pagePath in sitemap) {
if (sitemap.hasOwnProperty(pagePath)) {
const pageInSitemap = sitemap[pagePath];

// Fetch the page content
const pageContent = await client.getPageByPath({
pagePath,
channelName: channel,
locale
});

// Fetch the dynamic page item
let dynamicPageItem = null;
if(pageInSitemap.contentID) {
dynamicPageItem = await client.getContentItem({
contentID: pageInSitemap.contentID,
locale
});
}
// Add the page content to the allPageData object
allPageData[pagePath] = {
page: pageContent.page,
dynamicPageItem: dynamicPageItem
};
}
}

// Define the JSON output path for the aggregated data
const jsonOutputPath = path.join(__dirname, 'src', 'app', 'agility', 'data', 'pages.json');

// Ensure the directory exists
fs.mkdirSync(path.dirname(jsonOutputPath), { recursive: true });

// Write the aggregated data to the JSON file
fs.writeFileSync(jsonOutputPath, JSON.stringify(allPageData, null, 2), 'utf8');
}

prerenderPages();
11 changes: 5 additions & 6 deletions src/app/agility/pages/components/components.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { AgilityComponentsDirective } from "./components.directive"
import { AgilityComponentsService } from './components.service';


@Component({
selector: 'agility-component',
standalone: true,
Expand Down Expand Up @@ -33,9 +32,9 @@ export class AgilityComponents implements OnInit {
loadComponent() {

//get the module name
let moduleName = this.moduleObj?.value.module;

let moduleName = this.moduleObj?.module;


let moduleType = this.agilityComponentsService.getComponent(moduleName) as any;
if (!moduleType) {
console.warn(`No module found for ${moduleName}`);
Expand All @@ -53,14 +52,14 @@ export class AgilityComponents implements OnInit {

// Ensure the item property is set
if (componentRef.instance?.hasOwnProperty('item')) {
(componentRef.instance as any).item = this.moduleObj?.value.item;
(componentRef.instance as any).item = this.moduleObj?.item;
}

// Ensure the data property is set
if (componentRef.instance?.hasOwnProperty('data')) {
(componentRef.instance as any).data = {
item: this.moduleObj?.value.item,
image: this.moduleObj?.value.image,
item: this.moduleObj?.item,
image: this.moduleObj?.item.image,
page: this.page,
dynamicPageItem: this.dynamicPageItem
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AgilityService } from '../../../agility.service';
import { Router, RouterLink } from '@angular/router';
import { NgIf } from '@angular/common';
import { firstValueFrom } from 'rxjs';
import PrerenderedAgilityContentLists from '../../../data/content.json'

function decodeHTML(str: string): string {
return str.replace(/&#(\d+);/g, (_, dec) => String.fromCharCode(dec));
Expand Down Expand Up @@ -39,6 +40,17 @@ export class ModuleFeaturedPost implements OnInit {
}

async ngOnInit(): Promise<void> {


const categoriesData = PrerenderedAgilityContentLists['categories'];
if(categoriesData){
this.state.set(CATEGORIES_KEY, categoriesData as any);
}





try {
let categoriesRes = this.state.get(CATEGORIES_KEY, null as any);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AgilityService } from '../../../agility.service';
import { htmlDecode } from 'js-htmlencode';
import { firstValueFrom } from 'rxjs';
import { NgForOf, NgIf } from '@angular/common';
import PrerenderedAgilityContentLists from '../../../data/content.json'

const POSTS_KEY = makeStateKey<any[]>('posts');

Expand All @@ -26,9 +27,25 @@ export class ModulePostsListingComponent implements OnInit {
async ngOnInit(): Promise<void> {
this.moduleData = this.data.item.fields;

// Check if the posts data is already available in the transfer state
this.posts = this.transferState.get(POSTS_KEY, null as any);
const postData = PrerenderedAgilityContentLists['posts'];

if(postData){
this.transferState.set(POSTS_KEY, postData as any);
}

// set the posts to the transfer state
this.posts = this.transferState.get(POSTS_KEY, null as any).items.map((p: any) => {
return {
title: p.fields.title,
slug: p.fields.slug,
date: new Date(p.fields.date).toLocaleDateString(),
image: p.fields.image,
content: p.fields.content,
category: p.fields.category.fields.title || 'Uncategorized'
};
})

// fallback to API if no data in transfer state
if (!this.posts) {
const postsRes = await firstValueFrom(this.agilityService.getContentList('posts'));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
</p>
<a
*ngIf="item.primaryButton"
[href]="item.primaryButton.href"
[routerLink]="item.primaryButton.href"
[target]="item.primaryButton.target"
class="
inline-block
Expand Down
4 changes: 2 additions & 2 deletions src/app/agility/pages/pages.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<ng-container *ngIf="pageStatus === 404">Page not found.</ng-container>
<ng-container *ngIf="pageStatus === 500">Error loading page.</ng-container>
<ng-container *ngIf="pageStatus === 200">
<ng-container *ngIf="page?.zones"></ng-container>
<ng-container *ngIf="page?.zones">
<ng-container *ngFor="let zone of (page?.zones | keyvalue)">
<ng-container *ngFor="let moduleRef of (zone.value | keyvalue)">
<ng-container *ngFor="let moduleRef of zone.value">
<agility-component [moduleObj]="moduleRef" [page]="page" [dynamicPageItem]="dynamicPageItem">
</agility-component>
</ng-container>
Expand Down
Loading

0 comments on commit 628d849

Please sign in to comment.