UNPKG

@europeana/portal

Version:
458 lines (424 loc) 13.6 kB
/* eslint-disable camelcase */ /* ** Nuxt config ** Docs: https://nuxtjs.org/docs/configuration-glossary/ */ const APP_SITE_NAME = 'Europeana'; const APP_PKG_NAME = '@europeana/portal'; import versions from './pkg-versions.js'; import i18nLocales from './src/plugins/i18n/locales.js'; import i18nDateTime from './src/plugins/i18n/datetime.js'; import { parseQuery, stringifyQuery } from './src/plugins/vue-router.cjs'; import features, { featureIsEnabled, featureNotificationExpiration } from './src/features/index.js'; const buildPublicPath = () => { if (featureIsEnabled(process.env.ENABLE_JSDELIVR_BUILD_PUBLIC_PATH)) { return `https://cdn.jsdelivr.net/npm/${APP_PKG_NAME}@${versions[APP_PKG_NAME]}/.nuxt/dist/client`; } else { return process.env.NUXT_BUILD_PUBLIC_PATH; } }; export default { /* ** Runtime config */ publicRuntimeConfig: { app: { // TODO: rename env vars to prefix w/ APP_, except feature toggles baseUrl: process.env.PORTAL_BASE_URL, internalLinkDomain: process.env.INTERNAL_LINK_DOMAIN, featureNotification: process.env.APP_FEATURE_NOTIFICATION, featureNotificationExpiration: featureNotificationExpiration(process.env.APP_FEATURE_NOTIFICATION_EXPIRATION), schemaOrgDatasetId: process.env.SCHEMA_ORG_DATASET_ID, siteName: APP_SITE_NAME, search: { translateLocales: (process.env.APP_SEARCH_TRANSLATE_LOCALES || '').split(',') } }, auth: { strategies: { keycloak: { client_id: process.env.OAUTH_CLIENT, origin: process.env.OAUTH_ORIGIN || 'https://auth.europeana.eu', scope: (process.env.OAUTH_SCOPE || 'openid,profile,email,usersets').split(','), realm: process.env.OAUTH_REALM || 'europeana', response_type: process.env.OAUTH_RESPONSE_TYPE || 'code', access_type: process.env.OAUTH_ACCESS_TYPE || 'online', grant_type: process.env.OAUTH_GRANT_TYPE || 'authorization_code', token_type: process.env.OAUTH_TOKEN_TYPE || 'Bearer' } } }, axios: { baseURL: process.env.PORTAL_BASE_URL }, axiosLogger: { clearParams: process.env.AXIOS_LOGGER_CLEAR_PARAMS?.split(',') || ['wskey'], httpMethods: process.env.AXIOS_LOGGER_HTTP_METHODS?.toUpperCase().split(',') }, contentful: { spaceId: process.env.CTF_SPACE_ID, environmentId: process.env.CTF_ENVIRONMENT_ID, accessToken: { delivery: process.env.CTF_CDA_ACCESS_TOKEN, preview: process.env.CTF_CPA_ACCESS_TOKEN }, graphQlOrigin: process.env.CTF_GRAPHQL_ORIGIN }, elastic: { apm: { // Doc: https://www.elastic.co/guide/en/apm/agent/rum-js/current/configuration.html serverUrl: process.env.ELASTIC_APM_SERVER_URL, environment: process.env.ELASTIC_APM_ENVIRONMENT || 'development', logLevel: process.env.ELASTIC_APM_LOG_LEVEL || 'info', serviceName: 'portal-js', serviceVersion: versions[APP_PKG_NAME], frameworkName: 'Nuxt', frameworkVersion: versions['@nuxt/core'], ignoreUrls: [ /^\/(_nuxt|__webpack_hmr)\// ], ignoreUserAgents: [ 'kube-probe/' ] } }, europeana: { apis: { annotation: { url: process.env.EUROPEANA_ANNOTATION_API_URL, key: process.env.EUROPEANA_ANNOTATION_API_KEY || process.env.EUROPEANA_API_KEY }, entity: { url: process.env.EUROPEANA_ENTITY_API_URL || 'https://api.europeana.eu/entity', key: process.env.EUROPEANA_ENTITY_API_KEY || process.env.EUROPEANA_API_KEY }, newspaper: { url: process.env.EUROPEANA_NEWSPAPER_API_URL }, recommendation: { url: process.env.EUROPEANA_RECOMMENDATION_API_URL }, record: { url: process.env.EUROPEANA_RECORD_API_URL || 'https://api.europeana.eu/record', key: process.env.EUROPEANA_RECORD_API_KEY || process.env.EUROPEANA_API_KEY }, thumbnail: { url: process.env.EUROPEANA_THUMBNAIL_API_URL }, set: { url: process.env.EUROPEANA_SET_API_URL, key: process.env.EUROPEANA_SET_API_KEY || process.env.EUROPEANA_API_KEY }, entityManagement: { url: process.env.EUROPEANA_ENTITY_MANAGEMENT_API_URL }, iiifPresentation: { media: { url: process.env.EUROPEANA_MEDIA_IIIF_PRESENTATION_API_URL || 'https://iiif.europeana.eu/presentation' } } }, proxy: { media: { url: process.env.EUROPEANA_MEDIA_PROXY_URL } } }, features: features(), hotjar: { id: process.env.HOTJAR_ID, sv: process.env.HOTJAR_SNIPPET_VERSION }, http: { ports: { http: process.env.HTTP_PORT, https: process.env.HTTPS_PORT }, sslNegotiation: { enabled: featureIsEnabled(process.env.ENABLE_SSL_NEGOTIATION), datasetBlacklist: (process.env.SSL_DATASET_BLACKLIST || '').split(',') } }, matomo: { host: process.env.MATOMO_HOST, siteId: process.env.MATOMO_SITE_ID, loadWait: { delay: process.env.MATOMO_LOAD_WAIT_DELAY, retries: process.env.MATOMO_LOAD_WAIT_RETRIES } }, oauth: { origin: process.env.OAUTH_ORIGIN, realm: process.env.OAUTH_REALM, client: process.env.OAUTH_CLIENT, scope: process.env.OAUTH_SCOPE, responseType: process.env.OAUTH_RESPONSE_TYPE, accessType: process.env.OAUTH_ACCESS_TYPE, grantType: process.env.OAUTH_GRANT_TYPE, tokenType: process.env.OAUTH_TOKEN_TYPE } }, privateRuntimeConfig: { contentful: { graphQlOrigin: process.env.CTF_GRAPHQL_ORIGIN_PRIVATE || process.env.CTF_GRAPHQL_ORIGIN }, jira: { origin: process.env.JIRA_API_ORIGIN, username: process.env.JIRA_API_USERNAME, password: process.env.JIRA_API_PASSWORD, serviceDesk: { serviceDeskId: process.env.JIRA_API_SERVICE_DESK_ID, requestTypeId: process.env.JIRA_API_SERVICE_DESK_REQUEST_TYPE_ID, customFields: { pageUrl: process.env.JIRA_API_SERVICE_DESK_CUSTOM_FIELD_PAGE_URL, browser: process.env.JIRA_API_SERVICE_DESK_CUSTOM_FIELD_BROWSER, screensize: process.env.JIRA_API_SERVICE_DESK_CUSTOM_FIELD_SCREENSIZE } } }, redis: { url: process.env.REDIS_URL, tlsCa: process.env.REDIS_TLS_CA } }, /* ** Headers of the page */ head: { title: APP_SITE_NAME, htmlAttrs: { lang: 'en' }, meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: APP_SITE_NAME } ], link: [ { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } ] }, /* ** Customize the progress-bar color */ loading: { // Show progress bar immediately when testing, to aid detection that page // has started loading, then finished. throttle: process.env.NUXT_LOADING_THROTTLE || 200, css: false, duration: 2500, continuous: true }, /* ** Global CSS */ css: ['./assets/scss/style'], // BootstrapVue // Doc: https://bootstrap-vue.js.org/docs/ bootstrapVue: { // Set these two settings to `false` to prevent auto-importing of Bootstrap(Vue) // CSS. It will then need to be manually imported, e.g. with // assets/scss/bootstrap.scss bootstrapCSS: false, bootstrapVueCSS: false, // Tree shake plugins // // NOTE: do not register plugins globally (here) unless they are used widely; // import them locally into the views that need them instead. This // is to prevent large amounts of unused JS being sent upfront to clients. // As a general rule, only register globally if at least three views // use the plugin's components/directives. Also consider how often // those components are rendered based on placement in layout and // usage patterns by users, and the plugin's bundled size. componentPlugins: [ 'BadgePlugin', 'ButtonPlugin', 'CardPlugin', 'DropdownPlugin', 'FormCheckboxPlugin', 'FormGroupPlugin', 'FormInputPlugin', 'FormPlugin', 'FormRadioPlugin', 'FormTextareaPlugin', 'ImagePlugin', 'InputGroupPlugin', 'JumbotronPlugin', 'LayoutPlugin', 'LinkPlugin', 'ListGroupPlugin', 'ModalPlugin', 'NavbarPlugin', 'SidebarPlugin', 'ToastPlugin' ] }, /* ** Plugins to load before mounting the App */ plugins: [ '~/plugins/vue-matomo.client', '~/plugins/i18n/iso-locale', '~/plugins/hotjar.client', '~/plugins/link', '~/plugins/page', '~/plugins/vue-filters', '~/plugins/vue-directives', '~/plugins/vue-announcer.client', '~/plugins/vue-masonry.client', '~/plugins/vue-scrollto.client', '~/plugins/ab-testing', '~/plugins/features' ], buildModules: [ '~/modules/contentful-graphql', '~/modules/axios-logger', '~/modules/http', '~/modules/query-sanitiser', '@nuxtjs/auth' ], /* ** Nuxt.js modules */ modules: [ '~/modules/elastic-apm', '@nuxtjs/axios', 'bootstrap-vue/nuxt', 'cookie-universal-nuxt', ['@nuxtjs/i18n', { locales: i18nLocales, baseUrl: ({ $config }) => $config.app.baseUrl, defaultLocale: 'en', lazy: true, langDir: 'lang/', strategy: 'prefix', vueI18n: { fallbackLocale: 'en', silentFallbackWarn: true, dateTimeFormats: i18nDateTime }, // Disable redirects to account pages parsePages: false, pages: { 'account/callback': false, 'account/logout': false }, // Enable browser language detection to automatically redirect user // to their preferred language as they visit your app for the first time // Set to false to disable // NB: do not enable this in portal.js; our own l10n middleware handles it. detectBrowserLanguage: false, vuex: { // Module namespace moduleName: 'i18n', syncLocale: true, syncRouteParams: true } }] ], auth: { // Redirect routes: 'callback' option for keycloak redirects, // 'login' option for unauthorised redirection // 'home' option for redirection after login // no redirect on logout redirect: { login: '/account/login', logout: false, callback: '/account/callback', home: '/account' }, fullPathRedirect: true, strategies: { local: false, // Include oauth2 so that ~/plugins/authScheme can extend it _oauth2: { _scheme: 'oauth2' }, keycloak: { _scheme: '~/plugins/authScheme' } }, defaultStrategy: 'keycloak', plugins: ['~/plugins/apis', '~/plugins/user-likes.client'] }, router: { middleware: ['trailing-slash', 'legacy/index', 'l10n'], extendRoutes(routes) { const nuxtHomeRouteIndex = routes.findIndex(route => route.name === 'home'); routes[nuxtHomeRouteIndex] = { name: 'home', path: '/', component: 'src/pages/home/index.vue' }; const nuxtCollectionsPersonsOrPlacesRouteIndex = routes.findIndex(route => route.name === 'collections-persons-or-places'); routes.splice(nuxtCollectionsPersonsOrPlacesRouteIndex, 1); routes.push({ name: 'collections-persons', path: '/collections/persons', component: 'src/pages/collections/persons-or-places.vue' }); routes.push({ name: 'collections-places', path: '/collections/places', component: 'src/pages/collections/persons-or-places.vue' }); routes.push({ name: 'slug', path: '/*', component: 'src/pages/index.vue' }); }, linkExactActiveClass: 'exact-active-link', parseQuery, stringifyQuery }, serverMiddleware: [ // We can't use /api as that's reserved on www.europeana.eu for (deprecated) // access to Europeana APIs. { path: '/_api', handler: '~/server-middleware/api' }, { path: '/robots.txt', handler: '~/server-middleware/robots.txt' }, '~/server-middleware/logging', '~/server-middleware/referrer-policy', '~/server-middleware/record-json' ], /* ** Build configuration */ build: { // Do not enable extractCSS as it is unreliable. // See: https://github.com/nuxt/nuxt.js/issues/4219 extractCSS: false, extend(config, { isClient }) { // Extend webpack config only for client bundle if (isClient) { // Build source maps to aid debugging in production builds config.devtool = 'source-map'; } }, // Prevent irrelevant postcss warnings // See https://github.com/postcss/postcss/issues/1375 postcss: null, publicPath: buildPublicPath(), // swiper v8 (and its dependencies) is pure ESM and needs to be transpiled to be used by Vue2 transpile: ['dom7', 'ssr-window', 'swiper'] }, /* ** Enable modern builds */ modern: true, /* ** Render configuration */ render: { // Disable compression: leave it to a gateway/reverse proxy like NGINX or // Cloudflare. compressor: false, static: { maxAge: '1d' } }, srcDir: 'src/', // Opt-out of telemetry telemetry: false, watch: ['~/**/*.graphql'] };