1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-09-15 05:45:33 -04:00

generate /projects page with ISR instead of calling the API on every single request (closes #715)

https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration
This commit is contained in:
2021-12-30 18:58:14 -05:00
parent 8a44d1994c
commit f18277b940
4 changed files with 72 additions and 38 deletions

View File

@@ -71,7 +71,7 @@ const mdxComponents = {
/> />
), ),
gist: (props: { id: string; file?: string }) => <Gist {...props} />, gist: (props: { id: string; file?: string }) => <Gist {...props} />,
octocat: (props) => ( octocat: (props: { repo: string }) => (
<a className="no-underline" href={`https://github.com/${props.repo}`} target="_blank" rel="noopener noreferrer"> <a className="no-underline" href={`https://github.com/${props.repo}`} target="_blank" rel="noopener noreferrer">
<MarkGithubIcon size={24} verticalAlign="text-top" /> <MarkGithubIcon size={24} verticalAlign="text-top" />
<style jsx>{` <style jsx>{`

View File

@@ -48,7 +48,7 @@
"is-absolute-url": "^4.0.1", "is-absolute-url": "^4.0.1",
"lodash.groupby": "^4.6.0", "lodash.groupby": "^4.6.0",
"modern-normalize": "github:sindresorhus/modern-normalize#1fc6b5a86676b7ac8abc62d04d6080f92debc70f", "modern-normalize": "github:sindresorhus/modern-normalize#1fc6b5a86676b7ac8abc62d04d6080f92debc70f",
"next": "^v12.0.8-canary.13", "next": "v12.0.8-canary.13",
"next-mdx-remote": "^3.0.8", "next-mdx-remote": "^3.0.8",
"next-seo": "^4.28.1", "next-seo": "^4.28.1",
"next-sitemap": "^1.6.203", "next-sitemap": "^1.6.203",

View File

@@ -1,40 +1,12 @@
import useSWR from "swr"; import { graphql } from "@octokit/graphql";
import { fetcher } from "../lib/fetcher";
import Layout from "../components/Layout"; import Layout from "../components/Layout";
import Container from "../components/Container"; import Container from "../components/Container";
import PageTitle from "../components/page/PageTitle"; import PageTitle from "../components/page/PageTitle";
import RepositoryGrid from "../components/projects/RepositoryGrid"; import RepositoryGrid from "../components/projects/RepositoryGrid";
import Loading from "../components/loading/Loading";
import { ProjectsIcon } from "../components/icons"; import { ProjectsIcon } from "../components/icons";
import type { GetStaticProps } from "next";
function Grid() { export default function Projects({ repos }) {
// start fetching repos from API immediately
const { data, error } = useSWR("/api/projects/?sort=top&limit=12", fetcher);
if (error) {
return <div>error: {error.message}</div>;
}
// show spinning loading indicator if data isn't fetched yet
if (!data) {
return (
<div>
<Loading boxes={3} width={50} />
<style jsx>{`
div {
text-align: center;
margin: 2.5em auto;
}
`}</style>
</div>
);
}
// we have data!
return <RepositoryGrid repos={data} />;
}
export default function Projects() {
return ( return (
<Layout> <Layout>
<Container title="👨‍💻 Projects"> <Container title="👨‍💻 Projects">
@@ -45,8 +17,70 @@ export default function Projects() {
</> </>
} }
/> />
<Grid /> <RepositoryGrid repos={repos} />
</Container> </Container>
</Layout> </Layout>
); );
} }
export const getStaticProps: GetStaticProps = async () => {
// https://docs.github.com/en/graphql/reference/objects#repository
const { user } = await graphql(
`
query ($username: String!, $sort: String, $limit: Int) {
user(login: $username) {
repositories(
first: $limit
isLocked: false
isFork: false
ownerAffiliations: OWNER
privacy: PUBLIC
orderBy: { field: $sort, direction: DESC }
) {
edges {
node {
name
url
description
pushedAt
stargazerCount
forkCount
primaryLanguage {
name
color
}
}
}
}
}
}
`,
{
username: "jakejarvis",
limit: 12,
sort: "STARGAZERS",
headers: {
authorization: `token ${process.env.GH_PUBLIC_TOKEN}`,
},
}
);
const repos = user.repositories.edges.map(({ node: repo }) => ({
name: repo.name,
url: repo.url,
description: repo.description,
updatedAt: repo.pushedAt,
stars: repo.stargazerCount,
forks: repo.forkCount,
language: repo.primaryLanguage,
}));
return {
props: {
repos,
},
// fetch updated data and update page every 10 minutes (as needed)
// https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration
revalidate: 600,
};
};

View File

@@ -4085,7 +4085,7 @@ next-sitemap@^1.6.203:
matcher "^4.0.0" matcher "^4.0.0"
minimist "^1.2.5" minimist "^1.2.5"
next@^v12.0.8-canary.13: next@v12.0.8-canary.13:
version "12.0.8-canary.13" version "12.0.8-canary.13"
resolved "https://registry.yarnpkg.com/next/-/next-12.0.8-canary.13.tgz#55816604e4c20a62265cd519f7d6334bf99502b3" resolved "https://registry.yarnpkg.com/next/-/next-12.0.8-canary.13.tgz#55816604e4c20a62265cd519f7d6334bf99502b3"
integrity sha512-lAMWeXYEvZFWnqvEECe4BLwhxOfzAH8Jzkrb0ez02fCIg114F8gOgU3IgnBzuD2y4q2zKZ2Xqhaw7wJDqR4A4Q== integrity sha512-lAMWeXYEvZFWnqvEECe4BLwhxOfzAH8Jzkrb0ez02fCIg114F8gOgU3IgnBzuD2y4q2zKZ2Xqhaw7wJDqR4A4Q==
@@ -5899,9 +5899,9 @@ vfile@^4.0.0:
vfile-message "^2.0.0" vfile-message "^2.0.0"
vfile@^5.0.0: vfile@^5.0.0:
version "5.2.0" version "5.2.1"
resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.2.0.tgz#a32a646ff9251c274dbe8675644a39031025b369" resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.2.1.tgz#9278072d576e320917204a3291eec0b346c4ed5d"
integrity sha512-ftCpb6pU8Jrzcqku8zE6N3Gi4/RkDhRwEXSWudzZzA2eEOn/cBpsfk9aulCUR+j1raRSAykYQap9u6j6rhUaCA== integrity sha512-vXW5XKbELM6mLj88kmkJ+gjFGZ/2gTmpdqPDjs3y+qbvI5i7md7rba/+pbYEawa7t22W7ynywPV6lUUAS1WiYg==
dependencies: dependencies:
"@types/unist" "^2.0.0" "@types/unist" "^2.0.0"
is-buffer "^2.0.0" is-buffer "^2.0.0"