mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 04:25:22 -04:00
enable vercel analytics
This commit is contained in:
parent
cab79559e6
commit
afbdcc7b06
@ -89,12 +89,13 @@ const CornerCopyButton = styled(CopyButton, {
|
||||
|
||||
export type CodeBlockProps = ComponentProps<typeof Code> & {
|
||||
highlight?: boolean;
|
||||
withCopyButton?: boolean;
|
||||
};
|
||||
|
||||
const CodeBlock = ({ highlight, className, children, ...rest }: CodeBlockProps) => {
|
||||
const CodeBlock = ({ highlight, withCopyButton, className, children, ...rest }: CodeBlockProps) => {
|
||||
return (
|
||||
<Block highlight={highlight}>
|
||||
<CornerCopyButton source={children} />
|
||||
{withCopyButton && <CornerCopyButton source={children} />}
|
||||
<Code className={className?.replace("code-highlight", "").trim()} {...rest}>
|
||||
{children}
|
||||
</Code>
|
||||
|
@ -20,6 +20,7 @@ const CodeHybrid = ({ forceBlock, className, children, ...rest }: CodeHybridProp
|
||||
return (
|
||||
<CodeBlock
|
||||
highlight={prismEnabled && !classNames?.includes("language-plaintext")}
|
||||
withCopyButton
|
||||
className={className}
|
||||
{...rest}
|
||||
>
|
||||
|
@ -3,10 +3,11 @@
|
||||
// directory containing .mdx files relative to project root
|
||||
export const NOTES_DIR = "notes";
|
||||
|
||||
// normalize the timestamp saved when building/deploying (see next.config.js) and fall back to right now:
|
||||
// normalize the timestamp saved when building/deploying (see next.config.js) and fall back to right now
|
||||
export const RELEASE_DATE = new Date(process.env.RELEASE_DATE || Date.now()).toISOString();
|
||||
|
||||
// detect if running locally via `next dev` (phase is checked in next.config.js)
|
||||
export const IS_DEV_SERVER = process.env.IS_DEV_SERVER === "true";
|
||||
|
||||
// attempt to normalize the various environment flags
|
||||
export const BUILD_ENV = process.env.VERCEL_ENV || process.env.NEXT_PUBLIC_VERCEL_ENV || process.env.NODE_ENV;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import type { DefaultSeoProps, SocialProfileJsonLdProps, ArticleJsonLdProps } from "next-seo";
|
||||
|
||||
import * as config from ".";
|
||||
import { meJpg, faviconPng, faviconIco, appleTouchIconPng } from "./favicons";
|
||||
|
||||
import type { DefaultSeoProps, SocialProfileJsonLdProps, ArticleJsonLdProps } from "next-seo";
|
||||
|
||||
// Most of this file simply takes the data already defined in ./config.js and translates it into objects that are
|
||||
// compatible with next-seo's props:
|
||||
// https://github.com/garmeeh/next-seo#default-seo-configuration
|
||||
@ -49,6 +49,7 @@ export const defaultSeo: DefaultSeoProps = {
|
||||
{
|
||||
rel: "icon",
|
||||
href: faviconIco.src,
|
||||
sizes: "any", // https://twitter.com/subzey/status/1417099064949235712
|
||||
},
|
||||
{
|
||||
rel: "icon",
|
||||
|
@ -1,11 +1,13 @@
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import glob from "fast-glob";
|
||||
import matter from "gray-matter";
|
||||
import { marked } from "marked";
|
||||
import removeMarkdown from "remove-markdown";
|
||||
import pMap from "p-map";
|
||||
import pMemoize from "p-memoize";
|
||||
import matter from "gray-matter";
|
||||
import removeMarkdown from "remove-markdown";
|
||||
import { marked } from "marked";
|
||||
// @ts-ignore
|
||||
import { markedSmartypants } from "marked-smartypants";
|
||||
import { formatDate } from "./format-date";
|
||||
import { baseUrl } from "../config";
|
||||
import { NOTES_DIR } from "../config/constants";
|
||||
@ -36,6 +38,10 @@ export const getNoteData = async (
|
||||
const rawContent = await fs.readFile(fullPath, "utf8");
|
||||
const { data, content } = matter(rawContent);
|
||||
|
||||
// attach marked extensions:
|
||||
// https://marked.js.org/using_advanced#extensions
|
||||
marked.use(markedSmartypants());
|
||||
|
||||
// return both the parsed YAML front matter (with a few amendments) and the raw, unparsed markdown content
|
||||
return {
|
||||
frontMatter: {
|
||||
@ -45,7 +51,9 @@ export const getNoteData = async (
|
||||
// allow markdown formatting to appear in post titles in some places (rarely used):
|
||||
htmlTitle: marked.parseInline(data.title, {
|
||||
silent: true,
|
||||
smartypants: true,
|
||||
// these are deprecated and throw very noisy warnings but are still defaults, make it make sense...
|
||||
mangle: false,
|
||||
headerIds: false,
|
||||
}),
|
||||
slug,
|
||||
permalink: `${baseUrl}/${NOTES_DIR}/${slug}/`,
|
||||
|
6
lib/styles/fonts/index.ts
Normal file
6
lib/styles/fonts/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// a weird system but makes it impossible to accidentally end up with multiple imports of the same font. see:
|
||||
// https://nextjs.org/docs/pages/building-your-application/optimizing/fonts#reusing-fonts
|
||||
|
||||
export { default as Inter } from "./loaders/Inter";
|
||||
export { default as SourceCodePro } from "./loaders/SourceCodePro";
|
||||
export { default as ComicNeue } from "./loaders/ComicNeue";
|
13
lib/styles/fonts/loaders/ComicNeue.ts
Normal file
13
lib/styles/fonts/loaders/ComicNeue.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Comic_Neue as ComicNeueLoader } from "next/font/google";
|
||||
|
||||
const ComicNeue = ComicNeueLoader({
|
||||
weight: ["400", "700"],
|
||||
style: ["normal", "italic"],
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
fallback: ["'Comic Sans MS'", "'Comic Sans'"],
|
||||
adjustFontFallback: false,
|
||||
preload: false,
|
||||
});
|
||||
|
||||
export default ComicNeue;
|
10
lib/styles/fonts/loaders/Inter.ts
Normal file
10
lib/styles/fonts/loaders/Inter.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Inter as InterLoader } from "next/font/google";
|
||||
|
||||
const Inter = InterLoader({
|
||||
weight: "variable",
|
||||
subsets: ["latin"],
|
||||
display: "fallback",
|
||||
preload: true,
|
||||
});
|
||||
|
||||
export default Inter;
|
10
lib/styles/fonts/loaders/SourceCodePro.ts
Normal file
10
lib/styles/fonts/loaders/SourceCodePro.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Source_Code_Pro as SourceCodeProLoader } from "next/font/google";
|
||||
|
||||
const SourceCodePro = SourceCodeProLoader({
|
||||
weight: "variable",
|
||||
subsets: ["latin"],
|
||||
display: "fallback",
|
||||
preload: true,
|
||||
});
|
||||
|
||||
export default SourceCodePro;
|
@ -2,11 +2,11 @@ import { createStitches } from "@stitches/react";
|
||||
import type * as Stitches from "@stitches/react";
|
||||
|
||||
// misc. helpers
|
||||
import hexToRgba from "./utils/hex-to-rgba";
|
||||
import normalizeStyles from "./utils/normalize";
|
||||
import { rgba } from "polished";
|
||||
import normalizeCss from "stitches-normalize";
|
||||
|
||||
// web fonts
|
||||
import { Inter, SourceCodePro } from "./utils/fonts";
|
||||
import { Inter, SourceCodePro } from "./fonts";
|
||||
|
||||
// https://stitches.dev/docs/typescript#type-a-css-object
|
||||
export type CSS = Stitches.CSS<typeof stitchesConfig>;
|
||||
@ -30,7 +30,7 @@ export const {
|
||||
colors: {
|
||||
backgroundInner: "#ffffff",
|
||||
backgroundOuter: "#fcfcfc",
|
||||
backgroundHeader: hexToRgba("#fcfcfc", 0.7),
|
||||
backgroundHeader: rgba("#fcfcfc", 0.7),
|
||||
text: "#202020",
|
||||
mediumDark: "#515151",
|
||||
medium: "#5e5e5e",
|
||||
@ -40,7 +40,7 @@ export const {
|
||||
superLight: "#f4f4f4",
|
||||
superDuperLight: "#fbfbfb",
|
||||
link: "#0e6dc2",
|
||||
linkUnderline: hexToRgba("#0e6dc2", 0.4),
|
||||
linkUnderline: rgba("#0e6dc2", 0.4),
|
||||
success: "#44a248",
|
||||
error: "#ff1b1b",
|
||||
warning: "#f78200",
|
||||
@ -93,7 +93,7 @@ export const {
|
||||
alpha?: number;
|
||||
}) => ({
|
||||
// allow both pre-set rgba stitches variables and hex values
|
||||
$$underlineColor: color.startsWith("#") ? hexToRgba(color, alpha) : color,
|
||||
$$underlineColor: color.startsWith("#") ? rgba(color, alpha) : color,
|
||||
}),
|
||||
},
|
||||
});
|
||||
@ -102,7 +102,7 @@ export const darkTheme = createTheme({
|
||||
colors: {
|
||||
backgroundInner: "#1e1e1e",
|
||||
backgroundOuter: "#252525",
|
||||
backgroundHeader: hexToRgba("#252525", 0.85),
|
||||
backgroundHeader: rgba("#252525", 0.85),
|
||||
text: "#f1f1f1",
|
||||
mediumDark: "#d7d7d7",
|
||||
medium: "#b1b1b1",
|
||||
@ -112,7 +112,7 @@ export const darkTheme = createTheme({
|
||||
superLight: "#272727",
|
||||
superDuperLight: "#1f1f1f",
|
||||
link: "#88c7ff",
|
||||
linkUnderline: hexToRgba("#88c7ff", 0.4),
|
||||
linkUnderline: rgba("#88c7ff", 0.4),
|
||||
success: "#78df55",
|
||||
error: "#ff5151",
|
||||
warning: "#f2b702",
|
||||
@ -132,9 +132,12 @@ export const darkTheme = createTheme({
|
||||
},
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
export const globalStyles = globalCss(
|
||||
// @ts-ignore
|
||||
normalizeStyles,
|
||||
...normalizeCss({
|
||||
systemFonts: false,
|
||||
}),
|
||||
{
|
||||
body: {
|
||||
fontFamily: theme.fonts.sans,
|
||||
|
@ -1,32 +0,0 @@
|
||||
import {
|
||||
Inter as InterLoader,
|
||||
Source_Code_Pro as SourceCodeProLoader,
|
||||
Comic_Neue as ComicNeueLoader,
|
||||
} from "next/font/google";
|
||||
|
||||
const Inter = InterLoader({
|
||||
weight: "variable",
|
||||
subsets: ["latin"],
|
||||
display: "fallback",
|
||||
preload: true,
|
||||
});
|
||||
|
||||
const SourceCodePro = SourceCodeProLoader({
|
||||
weight: "variable",
|
||||
subsets: ["latin"],
|
||||
display: "fallback",
|
||||
preload: true,
|
||||
});
|
||||
|
||||
// only for use in pages/previously.tsx (and tree-shaken out everywhere else in production)
|
||||
const ComicNeue = ComicNeueLoader({
|
||||
weight: ["400", "700"],
|
||||
style: ["normal", "italic"],
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
fallback: ["'Comic Sans MS'", "'Comic Sans'"],
|
||||
adjustFontFallback: false,
|
||||
preload: false,
|
||||
});
|
||||
|
||||
export { Inter, SourceCodePro, ComicNeue };
|
@ -1,6 +0,0 @@
|
||||
import hexToRgbaOrig from "hex-to-rgba";
|
||||
|
||||
// removes spaces from default hex-to-rgba output
|
||||
const hexToRgba = (color: string, alpha?: number) => hexToRgbaOrig(color, alpha).replace(/\s/g, "");
|
||||
|
||||
export default hexToRgba;
|
@ -1,104 +0,0 @@
|
||||
/*! stitches-normalize | MIT License | https://github.com/jakejarvis/stitches-normalize */
|
||||
/*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */
|
||||
|
||||
import type * as Stitches from "@stitches/react";
|
||||
|
||||
const normalizeStyles: Record<string, Stitches.CSSProperties> = {
|
||||
"*, ::before, ::after": {
|
||||
boxSizing: "border-box",
|
||||
},
|
||||
html: {
|
||||
lineHeight: 1.15,
|
||||
tabSize: 4,
|
||||
// @ts-ignore
|
||||
WebkitTextSizeAdjust: "100%",
|
||||
},
|
||||
body: {
|
||||
margin: 0,
|
||||
},
|
||||
hr: {
|
||||
height: 0,
|
||||
color: "inherit",
|
||||
},
|
||||
"abbr[title]": {
|
||||
textDecoration: "underline dotted",
|
||||
},
|
||||
"b, strong": {
|
||||
fontWeight: "bolder",
|
||||
},
|
||||
"code, kbd, samp, pre": {
|
||||
fontSize: "1em",
|
||||
},
|
||||
small: {
|
||||
fontSize: "80%",
|
||||
},
|
||||
"sub, sup": {
|
||||
fontSize: "75%",
|
||||
lineHeight: 0,
|
||||
position: "relative",
|
||||
verticalAlign: "baseline",
|
||||
},
|
||||
sub: {
|
||||
bottom: "-0.25em",
|
||||
},
|
||||
sup: {
|
||||
top: "-0.5em",
|
||||
},
|
||||
table: {
|
||||
textIndent: 0,
|
||||
borderColor: "inherit",
|
||||
},
|
||||
"button, input, optgroup, select, textarea": {
|
||||
fontFamily: "inherit",
|
||||
fontSize: "100%",
|
||||
lineHeight: 1.15,
|
||||
margin: 0,
|
||||
// @ts-ignore
|
||||
WebkitAppearance: "button",
|
||||
},
|
||||
"button, select": {
|
||||
textTransform: "none",
|
||||
},
|
||||
legend: {
|
||||
padding: 0,
|
||||
},
|
||||
progress: {
|
||||
verticalAlign: "baseline",
|
||||
},
|
||||
summary: {
|
||||
display: "list-item",
|
||||
},
|
||||
"[type='search']": {
|
||||
outlineOffset: -2,
|
||||
// @ts-ignore
|
||||
WebkitAppearance: "textfield",
|
||||
},
|
||||
|
||||
// `-webkit` compatibility properties and rules
|
||||
"::-webkit-search-decoration": {
|
||||
// @ts-ignore
|
||||
WebkitAppearance: "none",
|
||||
},
|
||||
"::-webkit-inner-spin-button, ::-webkit-outer-spin-button": {
|
||||
height: "auto",
|
||||
},
|
||||
"::-webkit-file-upload-button": {
|
||||
font: "inherit",
|
||||
// @ts-ignore
|
||||
WebkitAppearance: "button",
|
||||
},
|
||||
|
||||
// `-moz` compatibility properties and rules
|
||||
"::-moz-focus-inner": {
|
||||
borderStyle: "none",
|
||||
padding: 0,
|
||||
},
|
||||
":-moz-focusring": {
|
||||
outline: "1px dotted ButtonText",
|
||||
},
|
||||
":-moz-ui-invalid": {
|
||||
boxShadow: "none",
|
||||
},
|
||||
};
|
||||
|
||||
export default normalizeStyles;
|
@ -4,7 +4,7 @@ const path = require("path");
|
||||
const { PHASE_DEVELOPMENT_SERVER } = require("next/constants");
|
||||
const config = require("./lib/config");
|
||||
|
||||
module.exports = (phase) => {
|
||||
module.exports = (/** @type {string} */ phase) => {
|
||||
/**
|
||||
* @type {import("next").NextConfig}
|
||||
*/
|
||||
@ -13,6 +13,7 @@ module.exports = (phase) => {
|
||||
reactStrictMode: true,
|
||||
trailingSlash: true,
|
||||
productionBrowserSourceMaps: true,
|
||||
transpilePackages: ["@novnc/novnc"],
|
||||
env: {
|
||||
BASE_URL:
|
||||
process.env.NEXT_PUBLIC_VERCEL_ENV !== "production" && process.env.NEXT_PUBLIC_VERCEL_URL !== undefined
|
||||
|
4658
package-lock.json
generated
4658
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
75
package.json
75
package.json
@ -11,7 +11,7 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_OPTIONS='--inspect' next dev",
|
||||
"dev": "next dev -H 0.0.0.0",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint . --ext js,jsx,ts,tsx,md,mdx"
|
||||
@ -19,40 +19,42 @@
|
||||
"dependencies": {
|
||||
"@giscus/react": "^2.2.8",
|
||||
"@hcaptcha/react-hcaptcha": "^1.8.1",
|
||||
"@novnc/novnc": "github:novnc/novnc#747603c0d5bbdc8ac31b81f7a1b31291a397d280",
|
||||
"@octokit/graphql": "^5.0.5",
|
||||
"@octokit/graphql-schema": "^14.1.0",
|
||||
"@primer/octicons": "^18.3.0",
|
||||
"@prisma/client": "^4.12.0",
|
||||
"@novnc/novnc": "git+https://git@github.com/novnc/novnc#e8ad466e45a21598debe81824744d85ff2323c7b",
|
||||
"@octokit/graphql": "^5.0.6",
|
||||
"@octokit/graphql-schema": "^14.11.0",
|
||||
"@primer/octicons": "^19.3.0",
|
||||
"@prisma/client": "^4.15.0",
|
||||
"@react-spring/web": "^9.7.2",
|
||||
"@sentry/node": "^7.47.0",
|
||||
"@sentry/tracing": "^7.47.0",
|
||||
"@sentry/node": "^7.55.2",
|
||||
"@sentry/tracing": "^7.55.2",
|
||||
"@stitches/react": "^1.2.8",
|
||||
"@vercel/analytics": "^1.0.1",
|
||||
"comma-number": "^2.1.0",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"dayjs": "^1.11.7",
|
||||
"dayjs": "^1.11.8",
|
||||
"fast-glob": "^3.2.12",
|
||||
"fathom-client": "^3.5.0",
|
||||
"feather-icons": "^4.29.0",
|
||||
"feed": "^4.2.2",
|
||||
"formik": "^2.2.9",
|
||||
"formik": "^2.4.2",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hex-to-rgba": "^2.0.1",
|
||||
"marked": "^4.3.0",
|
||||
"next": "13.3.0",
|
||||
"marked": "^5.1.0",
|
||||
"marked-smartypants": "^1.0.2",
|
||||
"next": "13.4.6",
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"next-seo": "^5.15.0",
|
||||
"next-seo": "^6.0.0",
|
||||
"obj-str": "^1.1.0",
|
||||
"p-map": "^5.5.0",
|
||||
"p-map": "^6.0.0",
|
||||
"p-memoize": "^7.1.1",
|
||||
"polished": "^4.2.2",
|
||||
"prop-types": "^15.8.1",
|
||||
"query-string": "^8.1.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-error-boundary": "^4.0.3",
|
||||
"react-error-boundary": "^4.0.10",
|
||||
"react-gist": "^1.2.4",
|
||||
"react-innertext": "^1.1.5",
|
||||
"react-intersection-observer": "^9.4.3",
|
||||
"react-intersection-observer": "^9.5.0",
|
||||
"react-is": "18.2.0",
|
||||
"react-player": "~2.10.1",
|
||||
"react-textarea-autosize": "^8.4.1",
|
||||
@ -63,40 +65,41 @@
|
||||
"remark-smartypants": "^2.0.0",
|
||||
"remark-unwrap-images": "^3.0.1",
|
||||
"remove-markdown": "^0.5.0",
|
||||
"simple-icons": "^8.10.0",
|
||||
"simple-icons": "^9.1.0",
|
||||
"sitemap": "^7.1.1",
|
||||
"swr": "^2.1.3"
|
||||
"stitches-normalize": "^2.0.0",
|
||||
"swr": "^2.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jakejarvis/eslint-config": "*",
|
||||
"@svgr/webpack": "^7.0.0",
|
||||
"@svgr/webpack": "^8.0.1",
|
||||
"@types/comma-number": "^2.1.0",
|
||||
"@types/marked": "^4.0.8",
|
||||
"@types/marked": "^5.0.0",
|
||||
"@types/node": "*",
|
||||
"@types/novnc__novnc": "^1.3.0",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
"@types/react": "^18.0.35",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@types/react-is": "^17.0.3",
|
||||
"@types/react": "^18.2.12",
|
||||
"@types/react-dom": "^18.2.5",
|
||||
"@types/react-is": "^18.2.0",
|
||||
"@types/remove-markdown": "^0.3.1",
|
||||
"@types/uglify-js": "^3.17.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.58.0",
|
||||
"@typescript-eslint/parser": "^5.58.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
||||
"@typescript-eslint/parser": "^5.59.11",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "~8.38.0",
|
||||
"eslint-config-next": "13.3.0",
|
||||
"eslint": "~8.43.0",
|
||||
"eslint-config-next": "13.4.6",
|
||||
"eslint-config-prettier": "~8.8.0",
|
||||
"eslint-plugin-mdx": "~2.0.5",
|
||||
"eslint-plugin-mdx": "~2.1.0",
|
||||
"eslint-plugin-prettier": "~4.2.1",
|
||||
"lint-staged": "^13.2.1",
|
||||
"prettier": "^2.8.7",
|
||||
"prisma": "^4.12.0",
|
||||
"lint-staged": "^13.2.2",
|
||||
"prettier": "^2.8.8",
|
||||
"prisma": "^4.15.0",
|
||||
"simple-git-hooks": "^2.8.1",
|
||||
"typescript": "^5.0.4",
|
||||
"typescript": "^5.1.3",
|
||||
"uglify-js": "^3.17.4"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"sharp": "^0.32.0"
|
||||
"sharp": "^0.32.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.x"
|
||||
@ -113,9 +116,9 @@
|
||||
"eslint"
|
||||
]
|
||||
},
|
||||
"packageManager": "npm@9.6.4",
|
||||
"packageManager": "npm@9.7.1",
|
||||
"volta": {
|
||||
"node": "18.16.0",
|
||||
"npm": "9.6.4"
|
||||
"npm": "9.7.1"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { DefaultSeo, SocialProfileJsonLd } from "next-seo";
|
||||
import { Analytics } from "@vercel/analytics/react";
|
||||
import * as Fathom from "fathom-client";
|
||||
import { ThemeProvider } from "../contexts/ThemeContext";
|
||||
import Layout from "../components/Layout";
|
||||
@ -73,6 +74,8 @@ const App = ({ Component, pageProps }: AppProps) => {
|
||||
<SocialProfileJsonLd {...socialProfileJsonLd} />
|
||||
|
||||
<ThemeProvider classNames={themeClassNames}>{getLayout(<Component {...pageProps} />)}</ThemeProvider>
|
||||
|
||||
<Analytics />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ const CLI = () => {
|
||||
<Image src={cliImg} href="https://www.npmjs.com/package/@jakejarvis/cli" alt="Terminal Screenshot" priority />
|
||||
|
||||
<H2 id="usage">Usage</H2>
|
||||
<CodeBlock>npx @jakejarvis/cli</CodeBlock>
|
||||
<CodeBlock withCopyButton>npx @jakejarvis/cli</CodeBlock>
|
||||
|
||||
<H2 id="inspired-by">Inspired by</H2>
|
||||
<UnorderedList>
|
||||
|
@ -9,7 +9,7 @@ import CodeInline from "../components/CodeInline";
|
||||
import HorizontalRule from "../components/HorizontalRule";
|
||||
import { Windows95Logo } from "../components/Icons";
|
||||
import { styled, theme } from "../lib/styles/stitches.config";
|
||||
import { ComicNeue } from "../lib/styles/utils/fonts";
|
||||
import { ComicNeue } from "../lib/styles/fonts";
|
||||
import type { ReactElement } from "react";
|
||||
|
||||
import img_wayback from "../public/static/images/previously/wayback.png";
|
||||
|
32
pages/robots.txt.ts
Normal file
32
pages/robots.txt.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { baseUrl } from "../lib/config";
|
||||
import type { GetServerSideProps } from "next";
|
||||
|
||||
export const getServerSideProps: GetServerSideProps<Record<string, never>> = async (context) => {
|
||||
const { res } = context;
|
||||
|
||||
// this production check should be unnecessary because "noindex" and "nofollow" are also set in a meta tag (see
|
||||
// DefaultSeo's props in pages/_app.tsx), but it doesn't hurt...
|
||||
const robots = `User-agent: *
|
||||
${
|
||||
process.env.NEXT_PUBLIC_VERCEL_ENV !== "production"
|
||||
? `Disallow: /`
|
||||
: `Allow: /
|
||||
|
||||
Sitemap: ${baseUrl}/sitemap.xml`
|
||||
}
|
||||
`;
|
||||
|
||||
res.setHeader("content-type", "text/plain; charset=utf-8");
|
||||
// cache on edge for one week
|
||||
res.setHeader("cache-control", "public, max-age=0, s-maxage=604800, stale-while-revalidate");
|
||||
|
||||
res.write(robots);
|
||||
res.end();
|
||||
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
};
|
||||
|
||||
// eslint-disable-next-line import/no-anonymous-default-export
|
||||
export default () => null;
|
@ -666,8 +666,8 @@ const Uses = () => {
|
||||
<strong>Tailscale</strong>
|
||||
</Link>{" "}
|
||||
and{" "}
|
||||
<Link href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/">
|
||||
<strong>Cloudflare Tunnel</strong>
|
||||
<Link href="https://developers.cloudflare.com/cloudflare-one/">
|
||||
<strong>Cloudflare Zero Trust</strong>
|
||||
</Link>{" "}
|
||||
to access my home network and VPSes from anywhere.
|
||||
</ListItem>
|
||||
@ -678,38 +678,65 @@ const Uses = () => {
|
||||
</H2>
|
||||
<UnorderedList>
|
||||
<ListItem>
|
||||
<Link href="https://www.tp-link.com/us/home-networking/wifi-router/archer-ax90/">
|
||||
<strong>TP-Link Archer AX90</strong>
|
||||
<Link href="https://store.ui.com/us/en/collections/unifi-dream-router/products/udr">
|
||||
<strong>UniFi Dream Router</strong>
|
||||
</Link>
|
||||
, plus:
|
||||
<UnorderedList>
|
||||
<ListItem>
|
||||
2x{" "}
|
||||
<Link href="https://store.ui.com/us/en/collections/unifi-switching-utility-mini/products/usw-flex-mini">
|
||||
Switch Flex Mini
|
||||
</Link>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Link href="https://store.ui.com/us/en/products/unifi-smart-power">SmartPower Plug</Link>{" "}
|
||||
<em>
|
||||
(<Link href="https://www.youtube.com/watch?v=iW1tHr4Y_cI">It's Comcastic!™</Link>)
|
||||
</em>
|
||||
</ListItem>
|
||||
</UnorderedList>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Link href="https://www.amazon.com/dp/B00HWML468/">
|
||||
<strong>Dell Inspiron 3647</strong>
|
||||
<strong>An overpowered custom homelab server</strong>, powered by an{" "}
|
||||
<Link href="https://www.asus.com/commercial-motherboard/q87me/">ASUS Q87M-E</Link> board,{" "}
|
||||
<Link href="https://www.intel.com/content/www/us/en/products/sku/80808/intel-core-i74790s-processor-8m-cache-up-to-4-00-ghz/specifications.html">
|
||||
i7-4790S
|
||||
</Link>
|
||||
, upgraded to a Core i7-4790S and 16 GB of memory to dress it up as a <em>really</em> crappy{" "}
|
||||
<Link href="https://www.vmware.com/products/esxi-and-esx.html">
|
||||
<strong>VMware ESXi</strong>
|
||||
, 32 GB of RAM, 3x recertified{" "}
|
||||
<Link href="https://www.westerndigital.com/products/internal-drives/data-center-drives/ultrastar-dc-hc550-hdd#0F38462">
|
||||
16TB WD Ultrastar
|
||||
</Link>{" "}
|
||||
server, running a few Ubuntu VMs with:
|
||||
drives, and Ubuntu Server 22.04, in a cheap{" "}
|
||||
<Link href="https://www.thermaltakeusa.com/versa-h22.html">Thermaltake Versa H22</Link> case with expensive{" "}
|
||||
<Link href="https://noctua.at/en/nf-a12x25-pwm">Noctua 🤎</Link> fans. Used mainly for local file sharing
|
||||
via Samba and running{" "}
|
||||
<Link href="https://github.com/jakejarvis/dotfiles/tree/main/lab">a few Docker containers</Link>, including:
|
||||
<UnorderedList>
|
||||
<ListItem>
|
||||
<Link href="https://www.plex.tv/">Plex</Link>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Link href="https://sonarr.tv/">Sonarr</Link>{" "}
|
||||
<Link href="https://sonarr.tv/">Sonarr</Link>, <Link href="https://radarr.video/">Radarr</Link>,{" "}
|
||||
<Link href="https://www.bazarr.media/">Bazarr</Link>,{" "}
|
||||
<Link href="https://github.com/Prowlarr/Prowlarr">Prowlarr</Link>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Link href="https://radarr.video/">Radarr</Link>
|
||||
<Link href="https://www.qbittorrent.org/">qBittorrent</Link> (web client)
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Link href="https://transmissionbt.com/">Transmission</Link> (via web client)
|
||||
<Link href="https://tautulli.com/">Tautulli</Link>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Link href="https://homebridge.io/">Homebridge</Link>
|
||||
<Link href="https://www.home-assistant.io/">Home Assistant</Link>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Link href="https://www.wireguard.com/">WireGuard</Link>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Link href="https://github.com/cloudflare/cloudflared">Cloudflare Tunnel</Link>
|
||||
</ListItem>
|
||||
<ListItem>Full post with more details coming soon!</ListItem>
|
||||
</UnorderedList>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
@ -722,15 +749,14 @@ const Uses = () => {
|
||||
2x{" "}
|
||||
<Link href="https://www.ecobee.com/en-us/smart-thermostats/smart-wifi-thermostat/">
|
||||
<strong>ecobee3 lite</strong>
|
||||
</Link>{" "}
|
||||
smart thermostats (HomeKit support was a must.)
|
||||
</Link>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
2x{" "}
|
||||
<Link href="https://www.sonos.com/en-us/shop/one.html">
|
||||
<strong>Sonos One</strong>
|
||||
</Link>{" "}
|
||||
(with Alexa turned off...allegedly.)
|
||||
(with Alexa turned off...hopefully? 🤫)
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
2x{" "}
|
||||
|
@ -1,4 +0,0 @@
|
||||
User-Agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://jarv.is/sitemap.xml
|
@ -1,7 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
@ -13,8 +17,20 @@
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve"
|
||||
"jsx": "preserve",
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user