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 Feb 25, 2022
1 parent 9c15587 commit 0719213
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 36 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 @@ -303,17 +303,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[];
}

type Body = string;

export interface EndpointOutput<Output extends Body = Body> {
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/core/render/core.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ComponentInstance, EndpointHandler, MarkdownRenderOptions, Params, Props, Renderer, RouteData, SSRElement } from '../../@types/astro';
import type { LogOptions } from '../logger.js';

import { renderEndpoint, renderPage } from '../../runtime/server/index.js';
import { renderEndpoint, renderToString } from '../../runtime/server/index.js';
import { getParams } from '../routing/index.js';
import { createResult } from './result.js';
import { findPathItemByKey, RouteCache, callGetStaticPaths } from './route-cache.js';
Expand Down Expand Up @@ -97,7 +97,7 @@ export async function render(opts: RenderOptions): Promise<string> {
scripts,
});

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

// inject <!doctype html> if missing (TODO: is a more robust check needed for comments, etc.?)
if (!legacyBuild && !/<!doctype html/i.test(html)) {
Expand Down
39 changes: 16 additions & 23 deletions packages/astro/src/runtime/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,20 @@ export function defineScriptVars(vars: Record<any, any>) {
return output;
}

// Renders an endpoint request to completion, returning the body.
export async function renderEndpoint(mod: EndpointHandler, params: any) {
const method = 'get';
const handler = mod[method];

if (!handler || typeof handler !== 'function') {
throw new Error(`Endpoint handler not found! Expected an exported function for "${method}"`);
}

const { body } = await mod.get(params);

return body;
}

// 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);
Expand All @@ -414,24 +428,10 @@ const uniqueElements = (item: any, index: number, all: any[]) => {
return index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children);
};

// Renders an endpoint request to completion, returning the body.
export async function renderEndpoint(mod: EndpointHandler, params: any) {
const method = 'get';
const handler = mod[method];

if (!handler || typeof handler !== 'function') {
throw new Error(`Endpoint handler not found! Expected an exported function for "${method}"`);
}

const { body } = await mod.get(params);

return body;
}

// 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);
export async function renderHead(result: SSRResult) {
const styles = Array.from(result.styles)
.filter(uniqueElements)
.map((style) => {
Expand All @@ -457,17 +457,10 @@ 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');
}

export async function renderAstroComponent(component: InstanceType<typeof AstroComponent>) {
Expand Down

0 comments on commit 0719213

Please sign in to comment.