diff --git a/dotcom-rendering/src/server/dev-index.html b/dotcom-rendering/src/server/dev-index.html index a085e5216b0..0c3d9de8cc6 100644 --- a/dotcom-rendering/src/server/dev-index.html +++ b/dotcom-rendering/src/server/dev-index.html @@ -97,6 +97,24 @@

Pages

>🏏 Cricket Match Page +
  • + 💷 Hosted Article +
  • +
  • + 💰 Hosted Video +
  • +
  • + 💸 Hosted Gallery +
  • { + recordTypeAndPlatform('article', 'web'); + + const frontendData = validateAsFEHostedContent(body); + const hostedContent = enhanceHostedContentType(frontendData); + const { html, prefetchScripts } = renderHtml({ + hostedContent, + }); + + res.status(200).set('Link', makePrefetchHeader(prefetchScripts)).send(html); +}; diff --git a/dotcom-rendering/src/server/render.hostedContent.web.tsx b/dotcom-rendering/src/server/render.hostedContent.web.tsx new file mode 100644 index 00000000000..81f76414bad --- /dev/null +++ b/dotcom-rendering/src/server/render.hostedContent.web.tsx @@ -0,0 +1,56 @@ +import { isString } from '@guardian/libs'; +import { HostedArticleLayout } from '../layouts/HostedArticleLayout'; +import { HostedGalleryLayout } from '../layouts/HostedGalleryLayout'; +import { getModulesBuild, getPathFromManifest } from '../lib/assets'; +import { renderToStringWithEmotion } from '../lib/emotion'; +import { polyfillIO } from '../lib/polyfill.io'; +import type { HostedContent } from '../types/hostedContent'; +import { htmlPageTemplate } from './htmlPageTemplate'; + +type Props = { + hostedContent: HostedContent; +}; + +export const renderHtml = ({ hostedContent }: Props) => { + const { type, frontendData } = hostedContent; + + const title = `Advertiser content hosted by the Guardian: ${frontendData.title} | The Guardian`; + + const HostedLayout = + type === 'gallery' ? HostedGalleryLayout : HostedArticleLayout; + const renderingTarget = 'Web'; + + const { html, extractedCss } = renderToStringWithEmotion( + , + ); + + // We don't send A/B tests or switches from frontend yet- do we need to? + const build = getModulesBuild({ + tests: {}, + switches: {}, + }); + + const prefetchScripts = [ + polyfillIO, + getPathFromManifest(build, 'frameworks.js'), + getPathFromManifest(build, 'index.js'), + ].filter(isString); + + // We currently don't send any of the data required for page config or window.guardian setup from frontend + const pageHtml = htmlPageTemplate({ + scriptTags: [], + css: extractedCss, + html, + title, + description: frontendData.standfirst, + // @ts-expect-error no config data + guardian: {}, + canonicalUrl: '', + renderingTarget: 'Web', + // @ts-expect-error no config data + config: {}, + weAreHiring: false, + }); + + return { html: pageHtml, prefetchScripts }; +}; diff --git a/dotcom-rendering/src/server/server.dev.ts b/dotcom-rendering/src/server/server.dev.ts index 1754d362a3a..13fd2d9ec4d 100644 --- a/dotcom-rendering/src/server/server.dev.ts +++ b/dotcom-rendering/src/server/server.dev.ts @@ -15,6 +15,7 @@ import { import { handleAppsAssets } from './handler.assets.apps'; import { handleEditionsCrossword } from './handler.editionsCrossword'; import { handleFront, handleTagPage } from './handler.front.web'; +import { handleHostedContent } from './handler.hostedContent.web'; import { handleCricketMatchPage, handleFootballMatchListPage, @@ -106,6 +107,8 @@ renderer.get('/FootballMatchListPage/*url', handleFootballMatchListPage); renderer.get('/FootballTablesPage/*url', handleFootballTablesPage); renderer.get('/CricketMatchPage/*url', handleCricketMatchPage); renderer.get('/FootballMatchSummaryPage/*url', handleFootballMatchPage); +renderer.get('/HostedContent/*url', handleHostedContent); + // POST routes for running frontend locally renderer.post('/Article', handleArticle); renderer.post('/Interactive', handleInteractive); @@ -121,6 +124,7 @@ renderer.post('/FootballMatchListPage', handleFootballMatchListPage); renderer.post('/FootballTablesPage', handleFootballTablesPage); renderer.post('/CricketMatchPage', handleCricketMatchPage); renderer.post('/FootballMatchSummaryPage', handleFootballMatchPage); +renderer.post('/HostedContent', handleHostedContent); renderer.get('/assets/rendered-items-assets', handleAppsAssets); diff --git a/dotcom-rendering/src/server/server.prod.ts b/dotcom-rendering/src/server/server.prod.ts index 821be7d9bc6..d43ed67bfa1 100644 --- a/dotcom-rendering/src/server/server.prod.ts +++ b/dotcom-rendering/src/server/server.prod.ts @@ -17,6 +17,7 @@ import { import { handleAppsAssets } from './handler.assets.apps'; import { handleEditionsCrossword } from './handler.editionsCrossword'; import { handleFront, handleTagPage } from './handler.front.web'; +import { handleHostedContent } from './handler.hostedContent.web'; import { handleCricketMatchPage, handleFootballMatchListPage, @@ -75,6 +76,7 @@ export const prodServer = (): void => { logRenderTime, handleFootballMatchPage, ); + app.post('/HostedContent', logRenderTime, handleHostedContent); app.post( '/EmailNewsletters',