Skip to content

Commit 71b576c

Browse files
committed
Merge branch 'release/26.5.0'
2 parents 0f3648b + e35f2aa commit 71b576c

21 files changed

Lines changed: 266 additions & 162 deletions

CHANGELOG

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
We follow the CalVer (https://calver.org/) versioning scheme: YY.MINOR.MICRO.
44

5+
26.5.0 (2026-02-26)
6+
===================
7+
8+
* Config updates to enable Angular SSR
9+
510
26.4.0 (2026-02-26)
611
===================
712

Dockerfile

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,37 @@
1-
# Build
2-
FROM node:22-alpine AS build
3-
1+
# Dependencies stage
2+
FROM node:22-alpine AS deps
43
WORKDIR /app
5-
64
COPY package*.json ./
7-
RUN npm install
5+
RUN npm ci --no-audit --no-fund
86

7+
# Build stage (SSR build output)
8+
FROM deps AS build
99
COPY . .
10+
RUN NG_BUILD_OPTIMIZE_CHUNKS=1 npx ng build --configuration=ssr --verbose
1011

11-
RUN npm link @angular/cli
12-
RUN NG_BUILD_OPTIMIZE_CHUNKS=1 ng build --verbose
13-
14-
# Dist
15-
FROM node:22-alpine AS dist
16-
17-
WORKDIR /code
18-
19-
COPY --from=build /app/dist /code/dist
20-
21-
# SSR
22-
FROM node:22-alpine AS ssr
23-
12+
# SSR runtime stage
13+
FROM build AS ssr
2414
WORKDIR /app
25-
26-
COPY package*.json ./
27-
RUN npm install
28-
29-
COPY . .
30-
31-
RUN npm link @angular/cli
32-
RUN NG_BUILD_OPTIMIZE_CHUNKS=1 ng build --configuration=ssr --verbose
33-
34-
RUN npm ci --omit=dev --ignore-scripts --no-audit --no-fund
35-
15+
RUN npm prune --omit=dev --no-audit --no-fund
3616
EXPOSE 4000
37-
3817
ENV PORT=4000
39-
4018
CMD ["node", "dist/osf/server/server.mjs"]
4119

42-
# Dev - run only
43-
FROM build AS dev
20+
# Static dist artifact stage
21+
FROM node:22-alpine AS dist
22+
WORKDIR /code
23+
COPY --from=build /app/dist /code/dist
4424

25+
# Dev server stage
26+
FROM deps AS dev
27+
COPY . .
4528
EXPOSE 4200
29+
CMD ["npx", "ng", "serve", "--host", "0.0.0.0"]
4630

47-
CMD ["ng", "serve"]
48-
49-
# Local Development - coding
31+
# Local development stage
5032
FROM node:22-alpine AS local-dev
5133
WORKDIR /app
52-
53-
# Install deps in the image (kept in container)
5434
COPY package*.json ./
55-
# COPY package-lock.docker.json ./package-lock.json
5635
RUN npm ci --no-audit --no-fund
57-
58-
# Expose Angular dev server
5936
EXPOSE 4200
37+
CMD ["npx", "ng", "serve", "--host", "0.0.0.0"]

angular.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,20 @@
117117
"namedChunks": true
118118
},
119119
"development": {
120+
"outputMode": "static",
121+
"server": false,
122+
"ssr": false,
123+
"optimization": false,
124+
"extractLicenses": false,
125+
"sourceMap": true,
126+
"fileReplacements": [
127+
{
128+
"replace": "src/environments/environment.ts",
129+
"with": "src/environments/environment.development.ts"
130+
}
131+
]
132+
},
133+
"dev-ssr": {
120134
"optimization": false,
121135
"extractLicenses": false,
122136
"sourceMap": true,
@@ -164,6 +178,9 @@
164178
"development": {
165179
"buildTarget": "osf:build:development"
166180
},
181+
"dev-ssr": {
182+
"buildTarget": "osf:build:dev-ssr"
183+
},
167184
"docker": {
168185
"buildTarget": "osf:build:docker"
169186
},

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "osf",
3-
"version": "26.4.0",
3+
"version": "26.5.0",
44
"scripts": {
55
"ng": "ng",
66
"analyze-bundle": "ng build --configuration=analyze-bundle && source-map-explorer dist/**/*.js --no-border-checks",
@@ -20,6 +20,7 @@
2020
"ngxs:store": "ng generate @ngxs/store:store --name --path",
2121
"prepare": "husky",
2222
"start": "ng serve",
23+
"start:ssr": "ng serve --configuration dev-ssr",
2324
"start:docker": "npm run check:config && ng serve --host 0.0.0.0 --port 4200 --poll 2000 --configuration development",
2425
"start:docker:local": "npm run check:config && ng serve --host 0.0.0.0 --port 4200 --poll 2000 --configuration docker",
2526
"test": "jest",

src/@types/ace-builds.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module 'ace-builds/src-noconflict/ext-language_tools';

src/app/app.config.server.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,42 @@ import { ApplicationConfig, mergeApplicationConfig } from '@angular/core';
22
import { provideServerRendering } from '@angular/platform-server';
33
import { provideServerRouting } from '@angular/ssr';
44

5+
import { SSR_CONFIG } from '@core/constants/ssr-config.token';
6+
import { ConfigModel } from '@core/models/config.model';
7+
58
import { appConfig } from './app.config';
69
import { serverRoutes } from './app.routes.server';
710

11+
import { existsSync, readFileSync } from 'node:fs';
12+
import { dirname, resolve } from 'node:path';
13+
import { fileURLToPath } from 'node:url';
14+
15+
function loadSsrConfig(): ConfigModel {
16+
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
17+
const configPath = resolve(serverDistFolder, '../browser/assets/config/config.json');
18+
19+
let config = {} as ConfigModel;
20+
21+
if (existsSync(configPath)) {
22+
try {
23+
config = JSON.parse(readFileSync(configPath, 'utf-8'));
24+
} catch {
25+
config = {} as ConfigModel;
26+
}
27+
}
28+
29+
return {
30+
...config,
31+
throttleToken: process.env['THROTTLE_TOKEN'] || '',
32+
} as ConfigModel;
33+
}
34+
835
const serverConfig: ApplicationConfig = {
9-
providers: [provideServerRendering(), provideServerRouting(serverRoutes)],
36+
providers: [
37+
provideServerRendering(),
38+
provideServerRouting(serverRoutes),
39+
{ provide: SSR_CONFIG, useFactory: loadSsrConfig },
40+
],
1041
};
1142

1243
export const config = mergeApplicationConfig(appConfig, serverConfig);

src/app/app.routes.server.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ export const serverRoutes: ServerRoute[] = [
141141
path: ':id/metadata/:recordId',
142142
renderMode: RenderMode.Server,
143143
},
144+
{
145+
path: ':id/wiki',
146+
renderMode: RenderMode.Server,
147+
},
144148
{
145149
path: ':id/files/**',
146150
renderMode: RenderMode.Server,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { InjectionToken } from '@angular/core';
2+
3+
import { ConfigModel } from '@core/models/config.model';
4+
5+
export const SSR_CONFIG = new InjectionToken<ConfigModel>('SSR_CONFIG');

src/app/core/helpers/i18n.helper.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
import { TranslateLoader, TranslateModuleConfig } from '@ngx-translate/core';
22
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
33

4+
import { isPlatformServer } from '@angular/common';
45
import { HttpClient } from '@angular/common/http';
6+
import { inject, PLATFORM_ID } from '@angular/core';
7+
8+
import { ENVIRONMENT } from '@core/provider/environment.provider';
59

610
function httpLoaderFactory(http: HttpClient): TranslateHttpLoader {
7-
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
11+
const platformId = inject(PLATFORM_ID);
12+
const environment = inject(ENVIRONMENT);
13+
const basePrefix = '/assets/i18n/';
14+
const webUrl = environment.webUrl?.replace(/\/+$/, '') ?? '';
15+
const prefix = isPlatformServer(platformId) && webUrl ? `${webUrl}${basePrefix}` : basePrefix;
16+
17+
return new TranslateHttpLoader(http, prefix, '.json');
818
}
919

1020
export const provideTranslation = (): TranslateModuleConfig => ({

0 commit comments

Comments
 (0)