diff --git a/config/config.example.yml b/config/config.example.yml index 0764edd080..f207d05add 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -23,10 +23,17 @@ universal: # Determining which styles are critical is a relatively expensive operation; this option is # disabled (false) by default to boost server performance at the expense of loading smoothness. inlineCriticalCss: false - # Path prefixes to enable SSR for. By default these are limited to paths of primary DSpace objects. - # NOTE: The "/handle/" path ensures Handle redirects work via SSR. The "/reload/" path ensures - # hard refreshes (e.g. after login) trigger SSR while fully reloading the page. - paths: [ '/home', '/items/', '/entities/', '/collections/', '/communities/', '/bitstream/', '/bitstreams/', '/handle/', '/reload/' ] + # Regexes to be run against the path of the page to check if SSR is allowed. + # If the path match any of the regexes it will be served directly in CSR. + # By default, excludes community and collection browse, global browse, global search, community list, and statistics. + excludePathRegexes: [ + /^\/communities\/[ 0-9a-f ]{ 8 }-[ 0-9a-f ]{ 4 }-[ 0-9a-f ]{ 4 }-[ 0-9a-f ]{ 4 }-[ 0-9a-f ]{ 12 }\/browse(\/.*)?$/i, + /^\/collections\/[ 0-9a-f ]{ 8 }-[ 0-9a-f ]{ 4 }-[ 0-9a-f ]{ 4 }-[ 0-9a-f ]{ 4 }-[ 0-9a-f ]{ 12 }\/browse(\/.*)?$/i, + /^\/browse\//, + /^\/search$/, + /^\/community-list$/, + /^\/statistics$/, + ] # Whether to enable rendering of Search component on SSR. # If set to true the component will be included in the HTML returned from the server side rendering. # If set to false the component will not be included in the HTML returned from the server side rendering. diff --git a/server.ts b/server.ts index cfab230ef5..28f356e0ca 100644 --- a/server.ts +++ b/server.ts @@ -241,7 +241,7 @@ export function app() { * The callback function to serve server side angular */ function ngApp(req, res) { - if (environment.universal.preboot && req.method === 'GET' && (req.path === '/' || environment.universal.paths.some(pathPrefix => req.path.startsWith(pathPrefix)))) { + if (environment.universal.preboot && req.method === 'GET' && (req.path === '/' || !isExcludedFromSsr(req.path, environment.universal.excludePathRegexes))) { // Render the page to user via SSR (server side rendering) serverSideRender(req, res); } else { @@ -625,6 +625,16 @@ function start() { } } +/** + * Check if SSR should be skipped for path + * + * @param path + * @param excludePathRegexes + */ +function isExcludedFromSsr(path: string, excludePathRegexes: RegExp[]): boolean { + return excludePathRegexes.some((regex) => regex.test(path)); +} + /* * The callback function to serve health check requests */ diff --git a/src/config/universal-config.interface.ts b/src/config/universal-config.interface.ts index 84678b6dcf..417023ddf0 100644 --- a/src/config/universal-config.interface.ts +++ b/src/config/universal-config.interface.ts @@ -32,9 +32,9 @@ export interface UniversalConfig extends Config { replaceRestUrl: boolean; /** - * Paths to enable SSR for. Defaults to the home page and paths in the sitemap. + * Regexes to match url's path and check if SSR is disabled for it. */ - paths: Array; + excludePathRegexes: RegExp[]; /** * Whether to enable rendering of search component on SSR diff --git a/src/environments/environment.production.ts b/src/environments/environment.production.ts index bdb953d181..a5d132a39d 100644 --- a/src/environments/environment.production.ts +++ b/src/environments/environment.production.ts @@ -11,7 +11,14 @@ export const environment: Partial = { inlineCriticalCss: false, transferState: true, replaceRestUrl: true, - paths: [ '/home', '/items/', '/entities/', '/collections/', '/communities/', '/bitstream/', '/bitstreams/', '/handle/', '/reload/' ], + excludePathRegexes: [ + /^\/communities\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/browse(\/.*)?$/i, + /^\/collections\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/browse(\/.*)?$/i, + /^\/browse\//, + /^\/search$/, + /^\/community-list$/, + /^\/statistics$/, + ], enableSearchComponent: false, enableBrowseComponent: false, }, diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 30ca741b36..ae7fcf69ae 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -14,7 +14,14 @@ export const environment: BuildConfig = { inlineCriticalCss: false, transferState: true, replaceRestUrl: false, - paths: [ '/home', '/items/', '/entities/', '/collections/', '/communities/', '/bitstream/', '/bitstreams/', '/handle/', '/reload/' ], + excludePathRegexes: [ + /^\/communities\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/browse(\/.*)?$/i, + /^\/collections\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/browse(\/.*)?$/i, + /^\/browse\//, + /^\/search$/, + /^\/community-list$/, + /^\/statistics$/, + ], enableSearchComponent: false, enableBrowseComponent: false, }, diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 502bae140a..168647e964 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -16,7 +16,14 @@ export const environment: Partial = { inlineCriticalCss: false, transferState: true, replaceRestUrl: false, - paths: [ '/home', '/items/', '/entities/', '/collections/', '/communities/', '/bitstream/', '/bitstreams/', '/handle/', '/reload/' ], + excludePathRegexes: [ + /^\/communities\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/browse(\/.*)?$/i, + /^\/collections\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/browse(\/.*)?$/i, + /^\/browse\//, + /^\/search$/, + /^\/community-list$/, + /^\/statistics$/, + ], enableSearchComponent: false, enableBrowseComponent: false, },