Skip to content

Commit

Permalink
feat: experimental prerendering feature
Browse files Browse the repository at this point in the history
  • Loading branch information
svedova committed May 30, 2024
1 parent 3f19e15 commit c5a6e11
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import TabConfigBuild from "./_components/TabConfigBuild";
import TabConfigHeaders from "./_components/TabConfigHeaders";
import TabConfigRedirects from "./_components/TabConfigRedirects";
import TabConfigServerless from "./_components/TabConfigServerless";
import TabConfigPrerender from "./_components/TabConfigPrerender";
import TabAPIKey from "./_components/TabAPIKey";
import { grey } from "@mui/material/colors";

Expand All @@ -41,6 +42,12 @@ export default function EnvironmentConfig() {
const { hash } = useLocation();
const navigate = useNavigate();

const prerendering = environment?.build.vars["SK_PRERENDER"] === "true";

if (prerendering && listItems[6].path !== "#prerender") {
listItems.splice(6, 0, { path: "#prerender", text: "Prerender" });
}

const Tab = useMemo(() => {
switch (hash) {
case "#domains":
Expand Down Expand Up @@ -80,6 +87,13 @@ export default function EnvironmentConfig() {
environment={environment}
setRefreshToken={setRefreshToken}
/>
{prerendering && (
<TabConfigPrerender
app={app}
environment={environment}
setRefreshToken={setRefreshToken}
/>
)}
<TabAPIKey
app={app}
environment={environment}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { useState } from "react";
import Box from "@mui/material/Box";
import TextField from "@mui/material/TextField";
import Button from "@mui/lab/LoadingButton";
import Switch from "@mui/material/Switch";
import FormControlLabel from "@mui/material/FormControlLabel";
import Typography from "@mui/material/Typography";
import Card from "~/components/Card";
import CardHeader from "~/components/CardHeader";
import CardFooter from "~/components/CardFooter";
import { useSubmitHandler } from "../actions";

interface Props {
app: App;
environment: Environment;
setRefreshToken: (v: number) => void;
}

export default function TabConfigRedirects({
environment: env,
app,
setRefreshToken,
}: Props) {
const prerenderEnabled = Boolean(env.build.prerender);

const [showPrerender, setShowPrerender] = useState(prerenderEnabled);

const { submitHandler, error, success, isLoading } = useSubmitHandler({
app,
env,
setRefreshToken,
});

if (!env) {
return <></>;
}

return (
<Card
id="prerender"
component="form"
sx={{ color: "white", mb: 2 }}
error={error}
success={success}
onSubmit={submitHandler}
>
<CardHeader
title="Prerender"
subtitle="Built-in prerendering functionality for crawlers."
/>

<Box sx={{ bgcolor: "rgba(0,0,0,0.2)", p: 1.75, pt: 1, mb: 4 }}>
<FormControlLabel
sx={{ pl: 0, ml: 0 }}
label="Enable prerendering"
control={
<Switch
color="secondary"
checked={showPrerender}
onChange={() => {
setShowPrerender(!showPrerender);
}}
/>
}
labelPlacement="start"
/>
<Typography sx={{ opacity: 0.5 }}>
Prerendering can enhance your SEO score and help with social media
crawlers craft powerful cards for your website.
</Typography>
</Box>
{showPrerender && (
<>
<Box sx={{ bgcolor: "rgba(0,0,0,0.2)", p: 1.75, pt: 1, mb: 4 }}>
<TextField
label="Wait for selector"
variant="filled"
autoComplete="off"
defaultValue={env?.build.prerender?.waitFor || ""}
fullWidth
name="build.prerender.waitFor"
placeholder=".my-class"
helperText={
"When specified the crawler will wait until the selector is found. The maximum wait time is 5 seconds."
}
/>
</Box>
<Box sx={{ bgcolor: "rgba(0,0,0,0.2)", p: 1.75, pt: 1, mb: 4 }}>
<TextField
label="Cache duration"
variant="filled"
autoComplete="off"
type="number"
defaultValue={env?.build.prerender?.waitFor || "2"}
fullWidth
name="build.prerender.cacheDuration"
placeholder="2"
sx={{
"& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button":
{
display: "none",
},
"& input[type=number]": {
MozAppearance: "textfield",
},
}}
helperText={
"The cache duration in hours. Each published deployment will empty the cache."
}
/>
</Box>
<Box sx={{ bgcolor: "rgba(0,0,0,0.2)", p: 1.75, pt: 1, mb: 4 }}>
<TextField
label="User Agent"
variant="filled"
autoComplete="off"
defaultValue={
env?.build.prerender?.matchUserAgent ||
"Googlebot|AdsBot|Twitterbot|Crawler|Facebot|LinkedInBot"
}
fullWidth
name="build.prerender.matchUserAgent"
helperText={
"Matched user agents will be shown the prerendered page."
}
/>
</Box>
</>
)}

<CardFooter>
<Button
type="submit"
variant="contained"
color="secondary"
loading={isLoading}
>
Save
</Button>
</CardFooter>
</Card>
);
}
15 changes: 15 additions & 0 deletions src/pages/apps/[id]/environments/[env-id]/config/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export const prepareBuildObject = (values: FormValues): BuildConfig => {
} catch {}
}

const hasPrerendering =
values["build.prerender.matchUserAgent"] ||
values["build.prerender.cacheDuration"] ||
values["build.prerender.waitFor"];

const build: BuildConfig = {
cmd: values["build.cmd"]?.trim() || "",
distFolder: (values["build.distFolder"] || "").trim(),
Expand All @@ -42,6 +47,13 @@ export const prepareBuildObject = (values: FormValues): BuildConfig => {
apiFolder: values["build.apiFolder"],
apiPathPrefix: values["build.apiPathPrefix"],
previewLinks: values["build.previewLinks"] === "on",
prerender: hasPrerendering
? {
waitFor: values["build.prerender.waitFor"]!,
matchUserAgent: values["build.prerender.matchUserAgent"]!,
cacheDuration: Number(values["build.prerender.cacheDuration"]),
}
: undefined,
redirects,
vars,
};
Expand Down Expand Up @@ -179,6 +191,9 @@ export interface FormValues {
"build.distFolder"?: string;
"build.headersFile"?: string;
"build.redirects"?: string;
"build.prerender.matchUserAgent"?: string;
"build.prerender.waitFor"?: string;
"build.prerender.cacheDuration"?: string;
"build.redirectsFile"?: string;
"build.apiFolder"?: string;
"build.apiPathPrefix"?: string;
Expand Down
7 changes: 7 additions & 0 deletions src/types/environment.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
declare type BuildConfig = {
prerender?: PrerenderConfig;
previewLinks?: boolean;
apiFolder?: string;
apiPathPrefix?: string;
Expand Down Expand Up @@ -41,6 +42,12 @@ interface Redirect {
hosts?: string[];
}

interface PrerenderConfig {
matchUserAgent: string;
waitFor: string;
cacheDuration: number;
}

declare type Environment = {
id?: string;
env: string; // Name of the environment - will be deprecated.
Expand Down

0 comments on commit c5a6e11

Please sign in to comment.