Skip to content

Commit

Permalink
feat: add renderHead util to server
Browse files Browse the repository at this point in the history
  • Loading branch information
Nate Moore committed Jan 20, 2022
1 parent 9e1bc17 commit 58cde2f
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 39 deletions.
11 changes: 0 additions & 11 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,17 +270,6 @@ export type Params = Record<string, string | undefined>;

export type Props = Record<string, unknown>;

export interface RenderPageOptions {
request: {
params?: Params;
url: URL;
canonicalURL: URL;
};
children: any[];
props: Props;
css?: string[];
}

/**
* Astro Renderer
* Docs: https://docs.astro.build/reference/renderer-reference/
Expand Down
5 changes: 2 additions & 3 deletions packages/astro/src/core/ssr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ import eol from 'eol';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { renderPage } from '../../runtime/server/index.js';
import { renderToString } from '../../runtime/server/index.js';
import { codeFrame, resolveDependency } from '../util.js';
import { getStylesForURL } from './css.js';
import { injectTags } from './html.js';
import { generatePaginateFunction } from './paginate.js';
import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from './routing.js';
import { createResult } from './result.js';
import { assignStaticPaths, ensureRouteCached, findPathItemByKey } from './route-cache.js';
Expand Down Expand Up @@ -233,7 +232,7 @@ export async function render(renderers: Renderer[], mod: ComponentInstance, ssrO
}
};

let html = await renderPage(result, Component, pageProps, null);
let html = await renderToString(result, Component, pageProps, null);

// inject tags
const tags: vite.HtmlTagDescriptor[] = [];
Expand Down
42 changes: 17 additions & 25 deletions packages/astro/src/runtime/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,24 +354,8 @@ export function defineScriptVars(vars: Record<any, any>) {
return output;
}

// Calls a component and renders it into a string of HTML
export async function renderToString(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any) {
const Component = await componentFactory(result, props, children);
let template = await renderAstroComponent(Component);
return template;
}

// Filter out duplicate elements in our set
const uniqueElements = (item: any, index: number, all: any[]) => {
const props = JSON.stringify(item.props);
const children = item.children;
return index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children);
};

// Renders a page to completion by first calling the factory callback, waiting for its result, and then appending
// styles and scripts into the head.
export async function renderPage(result: SSRResult, Component: AstroComponentFactory, props: any, children: any) {
const template = await renderToString(result, Component, props, children);
// Render hoisted scripts, styles, and links to end of <head />
export function renderHead(result: SSRResult) {
const styles = result._metadata.experimentalStaticBuild
? []
: Array.from(result.styles)
Expand All @@ -397,19 +381,27 @@ export async function renderPage(result: SSRResult, Component: AstroComponentFac
if (needsHydrationStyles) {
styles.push(renderElement('style', { props: { 'astro-style': true }, children: 'astro-root, astro-fragment { display: contents; }' }));
}

const links = Array.from(result.links)
.filter(uniqueElements)
.map((link) => renderElement('link', link));

// inject styles & scripts at end of <head>
let headPos = template.indexOf('</head>');
if (headPos === -1) {
return links.join('\n') + styles.join('\n') + scripts.join('\n') + template; // if no </head>, prepend styles & scripts
}
return template.substring(0, headPos) + links.join('\n') + styles.join('\n') + scripts.join('\n') + template.substring(headPos);
return links.join('\n') + styles.join('\n') + scripts.join('\n');
}

// Calls a component and renders it into a string of HTML
export async function renderToString(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any) {
const Component = await componentFactory(result, props, children);
let template = await renderAstroComponent(Component);
return template;
}

// Filter out duplicate elements in our set
const uniqueElements = (item: any, index: number, all: any[]) => {
const props = JSON.stringify(item.props);
const children = item.children;
return index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children);
};

export async function renderAstroComponent(component: InstanceType<typeof AstroComponent>) {
let template = '';

Expand Down

0 comments on commit 58cde2f

Please sign in to comment.