forked from vercel/next-react-server-components
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8bb054d
commit 23a3b46
Showing
44 changed files
with
8,307 additions
and
2,124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
node_modules | ||
.next | ||
*.log | ||
|
||
.cache | ||
.vercel | ||
.output | ||
|
||
public/build | ||
api/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,34 @@ | ||
# Next.js 12 React Server Components Demo (Alpha) | ||
# Welcome to Remix! | ||
|
||
This is the demo of Hacker News built with Next.js and React Server Components. Read our announcement here: [Next.js 12](https://nextjs.org/blog/next-12). | ||
- [Remix Docs](https://remix.run/docs) | ||
|
||
**Try the demo: https://next-news-rsc.vercel.sh** | ||
## Deployment | ||
|
||
### Development | ||
After having run the `create-remix` command and selected "Vercel" as a deployment target, you only need to [import your Git repository](https://vercel.com/new) into Vercel, and it will be deployed. | ||
|
||
To get started, run the following commands: | ||
If you'd like to avoid using a Git repository, you can also deploy the directory by running [Vercel CLI](https://vercel.com/cli): | ||
|
||
```sh | ||
npm i -g vercel | ||
vercel | ||
``` | ||
yarn | ||
yarn dev | ||
|
||
It is generally recommended to use a Git repository, because future commits will then automatically be deployed by Vercel, through its [Git Integration](https://vercel.com/docs/concepts/git). | ||
|
||
## Development | ||
|
||
To run your Remix app locally, make sure your project's local dependencies are installed: | ||
|
||
```sh | ||
npm install | ||
``` | ||
|
||
And visit localhost:3000. | ||
Afterwards, start the Remix development server like so: | ||
|
||
### Note | ||
```sh | ||
npm run dev | ||
``` | ||
|
||
React Server Components are still [experimental](https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html). To learn more about React Server Components, read our blog post: [Everything About React Server Components](https://vercel.com/blog/everything-about-react-server-components). | ||
Open up [http://localhost:3000](http://localhost:3000) and you should be ready to go! | ||
|
||
React Server Components support is a built-in feature of Next.js 12. Full documentation is available here: [React 18 — Next.js](https://nextjs.org/docs/advanced-features/react-18). | ||
If you're used to using the `vercel dev` command provided by [Vercel CLI](https://vercel.com/cli) instead, you can also use that, but it's not needed. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
const { createRequestHandler } = require("@remix-run/vercel"); | ||
|
||
module.exports = createRequestHandler({ | ||
build: require("./build") | ||
}); |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import React, { Suspense } from "react"; | ||
import { useRouter } from "next/router"; | ||
|
||
import Page from "./page"; | ||
import Item from "./item"; | ||
|
||
import getItem from "../lib/get-item"; | ||
import getComments from "../app/lib/get-comments"; | ||
|
||
let commentsData = {}; | ||
let storyData = {}; | ||
let fetchDataPromise = {}; | ||
|
||
function ItemPageWithData({ id }) { | ||
if (!commentsData[id]) { | ||
if (!fetchDataPromise[id]) { | ||
fetchDataPromise[id] = getItem(id) | ||
.then((story) => { | ||
storyData[id] = story; | ||
return getComments(story.comments); | ||
}) | ||
.then((c) => (commentsData[id] = c)); | ||
} | ||
throw fetchDataPromise[id]; | ||
} | ||
|
||
return ( | ||
<Page> | ||
<Item story={storyData[id]} comments={commentsData[id]} /> | ||
</Page> | ||
); | ||
} | ||
|
||
export default function ItemPage() { | ||
const { id } = useRouter().query; | ||
|
||
if (!id) return null; | ||
|
||
return ( | ||
<Suspense> | ||
<ItemPageWithData id={id} /> | ||
</Suspense> | ||
); | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { useState } from "react"; | ||
|
||
import timeAgo from "../lib/time-ago"; | ||
|
||
export default function Story({ | ||
id, | ||
title, | ||
date, | ||
url, | ||
user, | ||
score, | ||
commentsCount, | ||
}) { | ||
const { host } = url ? new URL(url) : { host: "#" }; | ||
const [voted, setVoted] = useState(false); | ||
|
||
return ( | ||
<div style={{ margin: "5px 0" }}> | ||
<div className="title"> | ||
<span | ||
style={{ | ||
cursor: "pointer", | ||
fontFamily: "sans-serif", | ||
marginRight: 5, | ||
color: voted ? "#ffa52a" : "#ccc", | ||
}} | ||
onClick={() => setVoted(!voted)} | ||
> | ||
▲ | ||
</span> | ||
<a href={url}>{title}</a> | ||
{url && ( | ||
<span className="source"> | ||
<a href={`http://${host}`}>{host.replace(/^www\./, "")}</a> | ||
</span> | ||
)} | ||
</div> | ||
<div className="meta"> | ||
{score} {plural(score, "point")} by{" "} | ||
<a href={`/user?id=${user}`}>{user}</a>{" "} | ||
<a href={`/item?id=${id}`}> | ||
{timeAgo(new Date(date)) /* note: we re-hydrate due to ssr */} ago | ||
</a>{" "} | ||
|{" "} | ||
<a href={`/item?id=${id}`}> | ||
{commentsCount} {plural(commentsCount, "comment")} | ||
</a> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
const plural = (n, s) => s + (n === 0 || n > 1 ? "s" : ""); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { hydrate } from "react-dom"; | ||
import { RemixBrowser } from "remix"; | ||
|
||
hydrate(<RemixBrowser />, document); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { renderToString } from "react-dom/server"; | ||
import { RemixServer } from "remix"; | ||
|
||
export default function handleRequest( | ||
request, | ||
responseStatusCode, | ||
responseHeaders, | ||
remixContext | ||
) { | ||
let markup = renderToString( | ||
<RemixServer context={remixContext} url={request.url} /> | ||
); | ||
|
||
responseHeaders.set("Content-Type", "text/html"); | ||
responseHeaders.set("Cache-Control", "s-maxage=5, stale-while-revalidate=5"); | ||
|
||
return new Response("<!DOCTYPE html>" + markup, { | ||
status: responseStatusCode, | ||
headers: responseHeaders, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
export default async function fetchData(type, delay = 0) { | ||
const [res] = await Promise.all([ | ||
fetch(`https://hacker-news.firebaseio.com/v0/${type}.json`), | ||
new Promise(res => setTimeout(res, (Math.random()) * delay)) | ||
]) | ||
new Promise((res) => setTimeout(res, Math.random() * delay)), | ||
]); | ||
if (res.status !== 200) { | ||
throw new Error(`Status ${res.status}`) | ||
throw new Error(`Status ${res.status}`); | ||
} | ||
return res.json() | ||
return res.json(); | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
Oops, something went wrong.