Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
2 changes: 1 addition & 1 deletion docs/latest/examples/common-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export const handler = define.handlers({
## WebSockets

Fresh provides first-class WebSocket support via `ctx.upgrade()`. See the full
[WebSocket guide](/docs/examples/websockets) for all options.
[WebSocket guide](/docs/advanced/websockets) for all options.

## Subdomain routing

Expand Down
2 changes: 1 addition & 1 deletion docs/toc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const toc: RawTableOfContents = {
["environment-variables", "Environment Variables", "link:latest"],
["head", "<head> element", "link:latest"],
["vite", "Vite Plugin Options", "link:latest"],
["websockets", "WebSockets", "link:latest"],
["opentelemetry", "OpenTelemetry", "link:latest"],
["api-reference", "API Reference", "link:latest"],
["troubleshooting", "Troubleshooting", "link:latest"],
Expand Down Expand Up @@ -107,7 +108,6 @@ const toc: RawTableOfContents = {
],
["active-links", "Active links", "link:latest"],
["session-management", "Session management", "link:latest"],
["websockets", "WebSockets", "link:latest"],
["common-patterns", "Common Patterns", "link:latest"],
],
},
Expand Down
2 changes: 1 addition & 1 deletion www/components/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function CodeBlock(
) {
return (
<pre
class="rounded-lg text-base leading-relaxed bg-slate-800 text-white p-4 sm:p-6 md:p-4 lg:p-6 2xl:p-8 overflow-x-auto"
class="rounded-lg text-sm leading-relaxed bg-slate-800 text-white p-3 sm:p-4 overflow-x-auto"
data-language={lang}
// deno-lint-ignore react-no-danger
><code dangerouslySetInnerHTML={{ __html: Prism.highlight(code, Prism.languages[lang], lang)}} /></pre>
Expand Down
4 changes: 2 additions & 2 deletions www/components/CodeWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function CodeWindow(props: CodeWindowProps) {
style={props.style}
>
<div class="flex items-stretch justify-start">
<div class="p-4 flex items-center">
<div class="p-3 flex items-center">
<svg
aria-hidden="true"
width="41"
Expand All @@ -28,7 +28,7 @@ export function CodeWindow(props: CodeWindowProps) {
<ellipse cx="35.9134" cy="5" rx="4.99155" ry="5" fill="#26C940" />
</svg>
</div>
<div class="p-4 w-full leading-none text-slate-400 text-base font-mono">
<div class="p-3 w-full leading-none text-slate-400 text-sm font-mono">
{props.name ?? ""}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion www/components/PageSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export function PageSection(props: JSX.HTMLAttributes<HTMLDivElement>) {
return (
<section
id={props.id ?? ""}
class={`w-full max-w-screen-xl mx-auto my-16 md:my-24 lg:my-32 px-4 sm:px-8 lg:px-16 2xl:px-0 flex flex-col gap-8 md:gap-16 ${
class={`w-full max-w-screen-xl mx-auto my-8 md:my-12 lg:my-16 px-4 sm:px-8 lg:px-16 2xl:px-0 flex flex-col gap-6 md:gap-8 ${
props.class ?? ""
}`}
>
Expand Down
2 changes: 1 addition & 1 deletion www/components/SideBySide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function SideBySide(props: SideBySideProps) {

return (
<div
class={`grid grid-cols-1 items-center gap-12 md:gap-16 xl:gap-32 ${
class={`grid grid-cols-1 items-center gap-8 md:gap-10 xl:gap-16 ${
props.reverseOnDesktop ? "[&>*]:md:first:order-1" : ""
} ${mdSplitClass} ${lgSplitClass} ${props.class ?? ""}`}
>
Expand Down
84 changes: 84 additions & 0 deletions www/components/homepage/APIRoutesSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { CodeBlock } from "../../components/CodeBlock.tsx";
import { CodeWindow } from "../../components/CodeWindow.tsx";
import { PageSection } from "../../components/PageSection.tsx";
import { SideBySide } from "../../components/SideBySide.tsx";
import { SectionHeading } from "../../components/homepage/SectionHeading.tsx";
import { FancyLink } from "../../components/FancyLink.tsx";

const apiCode = `import { createDefine } from "fresh";
const define = createDefine();

export const handlers = define.handlers({
GET(ctx) {
const user = db.getUser(ctx.params.id);
return Response.json(user);
},
POST(ctx) {
const body = await ctx.req.json();
const user = db.updateUser(ctx.params.id, body);
return Response.json(user);
},
DELETE(ctx) {
db.deleteUser(ctx.params.id);
return new Response(null, { status: 204 });
},
});`;

export function APIRoutesSection() {
return (
<PageSection>
<SideBySide
mdColSplit="3/2"
lgColSplit="3/2"
reverseOnDesktop
class="!items-start"
>
<div class="flex flex-col gap-4 md:sticky md:top-4">
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-api text-fresh"
width="2.5rem"
height="2.5rem"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<title>API routes icon</title>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M4 13h5" />
<path d="M12 16v-8h3a2 2 0 0 1 2 2v1a2 2 0 0 1 -2 2h-3" />
<path d="M20 8v8" />
<path d="M9 16v-5.5a2.5 2.5 0 0 0 -5 0v5.5" />
</svg>
<SectionHeading>Handlers for every method</SectionHeading>
<p>
Define{" "}
<code class="bg-gray-100 px-1.5 py-0.5 rounded text-sm font-mono">
GET
</code>,{" "}
<code class="bg-gray-100 px-1.5 py-0.5 rounded text-sm font-mono">
POST
</code>,{" "}
<code class="bg-gray-100 px-1.5 py-0.5 rounded text-sm font-mono">
DELETE
</code>{" "}
— any HTTP method as a named handler on your route. Fresh maps
requests to the right function automatically, with full type safety.
</p>
<FancyLink href="/docs/concepts/routing" class="mt-2">
Learn about handlers
</FancyLink>
</div>
<div class="flex flex-col gap-4">
<CodeWindow name="routes/users/[id].tsx">
<CodeBlock code={apiCode} lang="js" />
</CodeWindow>
</div>
</SideBySide>
</PageSection>
);
}
2 changes: 1 addition & 1 deletion www/components/homepage/DemoBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function DemoBox(props: DemoBoxProps) {
const innerFlip = props.flip ? "skew-y-2 skew-x-3" : "-skew-y-2 -skew-x-3";
return (
<div
class={`bg-gradient-to-br font-medium from-blue-200 via-green-300 to-yellow-200 p-8 py-12 text-center items-center flex justify-center ${outerFlip}`}
class={`bg-gradient-to-br font-medium from-blue-200 via-green-300 to-yellow-200 p-5 py-8 text-center items-center flex justify-center text-sm ${outerFlip}`}
>
<div class={`w-full ${innerFlip}`}>
{props.children}
Expand Down
2 changes: 1 addition & 1 deletion www/components/homepage/ExampleArrow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function ExampleArrow(
xmlns="http://www.w3.org/2000/svg"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;"
class={`w-12 -my-8 relative z-10 mx-auto ${props?.class ?? ""}`}
class={`w-8 -my-6 relative z-10 mx-auto ${props?.class ?? ""}`}
>
<path
d="M50.704,18c46.89,80.967 38.288,189.344 5.941,254.255"
Expand Down
7 changes: 4 additions & 3 deletions www/components/homepage/FormsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { ExampleArrow } from "../homepage/ExampleArrow.tsx";
import { FancyLink } from "../FancyLink.tsx";
import { FormSubmitDemo } from "../../islands/FormSubmitDemo.tsx";

const routingCode = `import { define } from "../utils.ts";
const routingCode = `import { createDefine } from "fresh";
const define = createDefine();

export const handler = define.handlers({
async POST(ctx) {
Expand All @@ -34,8 +35,8 @@ export function FormsSection() {
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-route-square-2 text-fresh"
width="4rem"
height="4rem"
width="2.5rem"
height="2.5rem"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
Expand Down
86 changes: 86 additions & 0 deletions www/components/homepage/HeadSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { CodeBlock } from "../../components/CodeBlock.tsx";
import { CodeWindow } from "../../components/CodeWindow.tsx";
import { PageSection } from "../../components/PageSection.tsx";
import { SideBySide } from "../../components/SideBySide.tsx";
import { SectionHeading } from "../../components/homepage/SectionHeading.tsx";
import { FancyLink } from "../../components/FancyLink.tsx";

const headCode = `import { Head } from "fresh/runtime";

export default function MyPage() {
return (
<>
<Head>
<title>My Page</title>
<meta name="description" content="..." />
<link rel="stylesheet" href="/styles.css" />
</Head>
<h1>Hello, world!</h1>
</>
);
}`;

export function HeadSection() {
return (
<PageSection>
<SideBySide
mdColSplit="3/2"
lgColSplit="3/2"
reverseOnDesktop
class="!items-start"
>
<div class="flex flex-col gap-4 md:sticky md:top-4">
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-file-code text-fresh"
width="2.5rem"
height="2.5rem"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<title>Head element icon</title>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M14 3v4a1 1 0 0 0 1 1h4" />
<path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" />
<path d="M10 13l-1 2l1 2" />
<path d="M14 13l1 2l-1 2" />
</svg>
<SectionHeading>
Full control of{" "}
<span
// deno-lint-ignore react-no-danger
dangerouslySetInnerHTML={{ __html: "&lt;head&gt;" }}
/>
</SectionHeading>
<p>
Use the{" "}
<code
class="bg-gray-100 px-1.5 py-0.5 rounded text-sm font-mono"
// deno-lint-ignore react-no-danger
dangerouslySetInnerHTML={{ __html: "&lt;Head&gt;" }}
/>{" "}
component from any page or island to set titles, meta tags,
stylesheets, and scripts — no hoisting hacks or side channels
needed.
</p>
<FancyLink href="/docs/advanced/head" class="mt-2">
<span
// deno-lint-ignore react-no-danger
dangerouslySetInnerHTML={{ __html: "Learn about &lt;Head&gt;" }}
/>
</FancyLink>
</div>
<div class="flex flex-col gap-4">
<CodeWindow name="routes/my-page.tsx">
<CodeBlock code={headCode} lang="jsx" />
</CodeWindow>
</div>
</SideBySide>
</PageSection>
);
}
9 changes: 7 additions & 2 deletions www/components/homepage/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@ export function Hero() {
<div class="bg-green-300 mt-0 pt-32 md:pt-48 !mb-0 bg-gradient-to-br from-blue-100 via-green-200 to-yellow-100">
<div class="md:grid grid-cols-5 gap-8 md:gap-16 items-center w-full max-w-screen-xl mx-auto px-4 md:px-8 lg:px-16 2xl:px-0">
<div class="flex-1 text-center md:text-left md:col-span-3 pb-8 md:pb-32">
<p class="italic text-gray-500 text-lg mb-4">Introducing Fresh:</p>
<h2 class="text-[calc(1rem+4vw)] leading-tight sm:text-5xl lg:text-6xl sm:tracking-tight sm:leading-none font-extrabold">
The simple, approachable, productive web framework
The framework so simple, you already know it.
</h2>
<p class="mt-6 text-lg sm:text-xl text-gray-700 text-balance max-w-prose">
No config files, no build step, no node_modules. Just one file and
you have a server with routing, JSX, and islands.
</p>
<div class="mt-12 flex flex-wrap justify-center items-stretch md:justify-start gap-4">
<FancyLink href="/docs/getting-started">Get started</FancyLink>
<CopyArea code={`deno run -Ar jsr:@fresh/init`} />
</div>
</div>
<div class="md:col-span-2 flex justify-center items-end">
<div class="md:col-span-2 flex justify-center items-end pb-8 md:pb-32">
<LemonTop />
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions www/components/homepage/IslandsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export function IslandsSection() {
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-beach text-fresh"
width="4rem"
height="4rem"
width="2.5rem"
height="2.5rem"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
Expand Down
4 changes: 2 additions & 2 deletions www/components/homepage/PartialsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export function PartialsSection() {
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-arrows-transfer-down text-fresh"
width="4rem"
height="4rem"
width="2.5rem"
height="2.5rem"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
Expand Down
18 changes: 15 additions & 3 deletions www/components/homepage/RecipeDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,25 @@ export const RecipeDemo = () => (
class="w-full grid grid-cols-1 md:grid-cols-[auto_1fr] text-left gap-6 items-stretch min-h-64"
>
<aside class="flex flex-col gap-2 underline p-6 pl-0 border-b md:border-r md:border-b-0 border-current text-left items-start justify-center">
<button type="button" f-partial="/recipes/lemonade">
<button
type="button"
f-partial="/recipes/lemonade"
class="cursor-pointer"
>
Lemonade
</button>
<button type="button" f-partial="/recipes/lemon-honey-tea">
<button
type="button"
f-partial="/recipes/lemon-honey-tea"
class="cursor-pointer"
>
Lemon-honey tea
</button>
<button type="button" f-partial="/recipes/lemondrop">
<button
type="button"
f-partial="/recipes/lemondrop"
class="cursor-pointer"
>
Lemondrop Martini
</button>
</aside>
Expand Down
15 changes: 7 additions & 8 deletions www/components/homepage/RenderingSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import { DemoBox } from "../../components/homepage/DemoBox.tsx";
import { ExampleArrow } from "../../components/homepage/ExampleArrow.tsx";

const serverCode = `export default function HomePage() {
const time = new Date().toLocaleString();
const now = Temporal.Now.plainDateTimeISO()
.toLocaleString("en-US");
return (
<p>Freshly server-rendered {time}</p>
<p>Freshly server-rendered {now}</p>
);
}`;

Expand All @@ -22,8 +23,8 @@ export function RenderingSection() {
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-atom text-fresh"
width="4rem"
height="4rem"
width="2.5rem"
height="2.5rem"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
Expand Down Expand Up @@ -56,10 +57,8 @@ export function RenderingSection() {
<ExampleArrow class="ml-[55%]" />{" "}
<DemoBox>
<p>
Freshly server-rendered {new Date().toLocaleString("default", {
dateStyle: "medium",
timeStyle: "medium",
})} UTC
Freshly server-rendered{" "}
{Temporal.Now.plainDateTimeISO().toLocaleString("en-US")}
</p>
</DemoBox>
</div>
Expand Down
Loading
Loading