I've created an ApiService using the TransferState API to cache data from a wordpress:
get(url, id) {
const key = makeStateKey(id);
if (this.transferState.hasKey(key)) {
const item = this.transferState.get(key, null);
return of(item);
} else {
return this.http.get(url).pipe(
map(items => {
this.transferState.set(key, items);
return items;
})
);
}
}
Then i'm using it to get data:
this.apiService.get(environment.url + '/wp-json/wp/v2/posts').subscribe(res => {
this.posts = res;
});
This works well, and when run, calls the API the first time, then second time is always cached.
When statically generated:
/index.html
<script id="my-app-state" type="application/json">
<!-- top level page data -->
</script>
/posts/index.html
<script id="my-app-state" type="application/json">
<!-- top level page data -->
<!-- posts data -->
</script>
If I land on the exact html page /posts/index.html, the data is loaded from the TransferState cache https://kmturley.github.io/angular-universal-wordpress-cms/frontend/dist/browser/sample-page
If I land on /index.html, and navigate to /posts it uses html5 routes, the data is not available in the script tag. and is loaded via http instead https://kmturley.github.io/angular-universal-wordpress-cms/frontend/dist/browser/
From what I understand the reason is because you land on a real static index.html file, containing the then when navigating, all subsequent pages are not loading .html files, they are actually html5 routes /posts.
So the question is, how can I get the TransferState cache to use the from the /posts/index.html file which was statically generated?
Potential solutions:
- Loading all data upfront (works, but pages are 1.1MB each)
- Putting data into a static file which can be loaded by ajax
- disabling html5 routing, so user hits static .html file with correct script tag
- some undocumented angular solution??
Static generated demo:
https://kmturley.github.io/angular-universal-wordpress-cms/frontend/dist/browser/
Static generated source:
https://github.com/kmturley/angular-universal-wordpress-cms/tree/gh-pages/frontend/dist/browser
Full codebase is here:
I managed to solve this using a workaround. I created a new TransferState JSON which returns data as JSON, which can be shared between multiple pages:
https://github.com/kmturley/angular-universal-google-apis/blob/master/src/app/shared/transfer_state_json.ts
and then modified the renderModuleFactory to return html and data separately:
https://github.com/kmturley/angular-universal-google-apis/blob/master/utils.ts#L53
so that it can be saved to a .json file in prerender.ts:
https://github.com/kmturley/angular-universal-google-apis/blob/master/prerender.ts#L53
You can see a demo static version using the json here:
https://kimturley.co.uk/angular-universal-google-apis/dist/browser/
and the source code here:
https://github.com/kmturley/angular-universal-google-apis