Testing SSR redirects
This commit is contained in:
parent
049ab7dc96
commit
6b09b8e31b
11 changed files with 86 additions and 10 deletions
|
@ -5,6 +5,10 @@ interface Product {
|
|||
image: string;
|
||||
}
|
||||
|
||||
interface User {
|
||||
id: number;
|
||||
}
|
||||
|
||||
//let origin: string;
|
||||
const { mode } = import.meta.env;
|
||||
const origin = mode === 'develepment' ? `http://localhost:3000` : `http://localhost:8085`;
|
||||
|
@ -31,3 +35,10 @@ export async function getProduct(id: number): Promise<Product> {
|
|||
return product;
|
||||
});
|
||||
}
|
||||
|
||||
export async function getUser(): Promise<User> {
|
||||
return get<User>(`/api/user`, async response => {
|
||||
const user: User = await response.json();
|
||||
return user;
|
||||
});
|
||||
}
|
||||
|
|
22
examples/ssr/src/pages/cart.astro
Normal file
22
examples/ssr/src/pages/cart.astro
Normal file
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
import { getUser } from '../api';
|
||||
|
||||
const isLoggedIn = false;
|
||||
|
||||
if(!isLoggedIn) {
|
||||
return Astro.redirect('/');
|
||||
}
|
||||
|
||||
// This person is logged in
|
||||
const user = { name: 'test'} // await getUser();
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Logged in Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Logged in page</h1>
|
||||
<h2>User: {user.name}</h2>
|
||||
</body>
|
||||
</html>
|
7
examples/ssr/tsconfig.json
Normal file
7
examples/ssr/tsconfig.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2015", "DOM"],
|
||||
"module": "ES2022",
|
||||
"types": ["astro/env"]
|
||||
}
|
||||
}
|
|
@ -130,6 +130,8 @@ export async function staticBuild(opts: StaticBuildOptions) {
|
|||
|
||||
const topLevelImports = new Set([
|
||||
// Any component that gets hydrated
|
||||
// 'components/Counter.jsx'
|
||||
// { 'components/Counter.jsx': 'counter.hash.js' }
|
||||
...metadata.hydratedComponentPaths(),
|
||||
// Client-only components
|
||||
...metadata.clientOnlyComponentPaths(),
|
||||
|
|
|
@ -62,7 +62,7 @@ interface RenderOptions {
|
|||
site?: string;
|
||||
}
|
||||
|
||||
export async function render(opts: RenderOptions): Promise<string> {
|
||||
export async function render(opts: RenderOptions): Promise<string | { location: string }> {
|
||||
const { legacyBuild, links, logging, origin, markdownRender, mod, pathname, scripts, renderers, resolve, route, routeCache, site } = opts;
|
||||
|
||||
const [params, pageProps] = await getParamsAndProps({
|
||||
|
@ -99,6 +99,10 @@ export async function render(opts: RenderOptions): Promise<string> {
|
|||
|
||||
let html = await renderToString(result, Component, pageProps, null);
|
||||
|
||||
if(typeof html === 'object') {
|
||||
return html;
|
||||
}
|
||||
|
||||
// handle final head injection if it hasn't happened already
|
||||
if (html.indexOf("<!--astro:head:injected-->") == -1) {
|
||||
html = await renderHead(result) + html;
|
||||
|
|
|
@ -116,7 +116,7 @@ export async function render(renderers: Renderer[], mod: ComponentInstance, ssrO
|
|||
site: astroConfig.buildOptions.site,
|
||||
});
|
||||
|
||||
if (route?.type === 'endpoint') {
|
||||
if (route?.type === 'endpoint' || typeof content === 'object') {
|
||||
return content;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,15 @@ export function createResult(args: CreateResultArgs): SSRResult {
|
|||
params,
|
||||
url,
|
||||
},
|
||||
redirect(path: string) {
|
||||
// TOOD property response
|
||||
return {
|
||||
status: 301,
|
||||
headers: {
|
||||
Location: path
|
||||
}
|
||||
};
|
||||
},
|
||||
resolve(path: string) {
|
||||
if (!legacyBuild) {
|
||||
let extra = `This can be replaced with a dynamic import like so: await import("${path}")`;
|
||||
|
|
|
@ -420,16 +420,27 @@ export async function renderEndpoint(mod: EndpointHandler, params: any) {
|
|||
}
|
||||
|
||||
// Calls a component and renders it into a string of HTML
|
||||
export async function renderToString(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any) {
|
||||
export async function renderToString(result: SSRResult, componentFactory: AstroComponentFactory,
|
||||
props: any, children: any): Promise<string | any> {
|
||||
const Component = await componentFactory(result, props, children);
|
||||
let template = await renderAstroComponent(Component);
|
||||
|
||||
// <!--astro:head--> injected by compiler
|
||||
// Must be handled at the end of the rendering process
|
||||
if (template.indexOf('<!--astro:head-->') > -1) {
|
||||
template = template.replace('<!--astro:head-->', await renderHead(result));
|
||||
if(Object.prototype.toString.call(Component) === '[object AstroComponent]') {
|
||||
let template = await renderAstroComponent(Component);
|
||||
|
||||
// HACK
|
||||
if(typeof template === 'object') {
|
||||
return template;
|
||||
}
|
||||
|
||||
// <!--astro:head--> injected by compiler
|
||||
// Must be handled at the end of the rendering process
|
||||
if (template.indexOf('<!--astro:head-->') > -1) {
|
||||
template = template.replace('<!--astro:head-->', await renderHead(result));
|
||||
}
|
||||
return template;
|
||||
} else {
|
||||
return Component;
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
// Filter out duplicate elements in our set
|
||||
|
@ -482,7 +493,8 @@ export async function renderAstroComponent(component: InstanceType<typeof AstroC
|
|||
}
|
||||
}
|
||||
|
||||
return unescapeHTML(await _render(template));
|
||||
let html = await _render(template);
|
||||
return unescapeHTML(html);
|
||||
}
|
||||
|
||||
function componentIsHTMLElement(Component: unknown) {
|
||||
|
|
4
packages/astro/test/fixtures/static build/src/components/UsedNested.astro
vendored
Normal file
4
packages/astro/test/fixtures/static build/src/components/UsedNested.astro
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
<script type="module" hoist>
|
||||
import "../scripts/used-nested";
|
||||
</script>
|
4
packages/astro/test/fixtures/static build/src/pages/subpage/page.astro
vendored
Normal file
4
packages/astro/test/fixtures/static build/src/pages/subpage/page.astro
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
import Component from '../../components/UsedNested.astro';
|
||||
---
|
||||
<Component/>
|
1
packages/astro/test/fixtures/static build/src/scripts/used-nested.js
vendored
Normal file
1
packages/astro/test/fixtures/static build/src/scripts/used-nested.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
console.log("i am used from a component that's used from a nested page");
|
Loading…
Reference in a new issue