diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1c93ae8d..128d3b02 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ The repository is structured as follows: - `api`: The API server which is served via `https://api.docs.page`. This is an express application which handles tasks such as fetching content from GitHub and markdown parsing. - `og`: A Next.js application which serves the Open Graph images for documentation pages. -- `website`: A Remix application which serves the main `https://docs.page` website, and the documentation rendering for each repository. +- `website`: A Next.js application which serves the main `https://docs.page` website, and the documentation rendering for each repository. - `packages/cli`: A CLI for running various commands and scripts for initialization, checking etc. Used locally and on CI environments. ## Running docs.page @@ -21,6 +21,6 @@ Generally, you'll want to interface with the website and api. To run these concu bun dev ``` -This will start the website on `http://localhost:5173` and the api on `http://localhost:8080`. +This will start the website on `http://localhost:3000` and the api on `http://localhost:8080`. > The API requires a `GITHUB_APP_ID` and `GITHUB_APP_PRIVATE_KEY` to be set in your environment. These are used to authenticate with the GitHub API. You can create a GitHub App in your GitHub account settings. \ No newline at end of file diff --git a/api/src/config/v1.schema.ts b/api/src/config/v1.schema.ts index f2cd52a9..cca68f91 100644 --- a/api/src/config/v1.schema.ts +++ b/api/src/config/v1.schema.ts @@ -78,10 +78,12 @@ export const V1ConfigSchema = z const config: Config = { name: v1.name, description: v1.description, - favicon: v1.favicon, + favicon: { + light: v1.favicon, + dark: v1.favicon, + }, socialPreview: v1.socialPreview, logo: { - href: "/", light: v1.logo, dark: v1.logoDark, }, diff --git a/bun.lockb b/bun.lockb index 59fb2a70..07d0b226 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/og/package.json b/og/package.json index 626b3cc1..3dd12601 100644 --- a/og/package.json +++ b/og/package.json @@ -15,8 +15,8 @@ "@types/react-dom": "18.0.10", "@vercel/og": "^0.0.21", "next": "13.1.0", - "react": "18.3.0-canary-bb0944fe5-20240313", - "react-dom": "18.2.0", + "react": "18.3.1", + "react-dom": "18.3.1", "typescript": "4.9.4" } } diff --git a/package.json b/package.json index 147f79d5..e9e73d81 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "dev": "concurrently \"npm run dev:api\" \"npm run dev:website\"", "dev:api": "cd api && bun dev", "dev:website": "cd website && npm run dev", - "check": "npx @biomejs/biome check --write ." + "check": "bunx @biomejs/biome check --write ." }, "dependencies": { "typescript": "^5.5.3" @@ -13,12 +13,7 @@ "@biomejs/biome": "1.8.3", "concurrently": "^7.0.0" }, - "workspaces": [ - "api", - "website", - "og", - "packages/*" - ], + "workspaces": ["api", "website", "og", "packages/*"], "patchedDependencies": { "@remix-run/react@2.9.2": "patches/@remix-run%2Freact@2.9.2.patch" } diff --git a/website/.gitignore b/website/.gitignore index 7c028014..fd3dbb57 100644 --- a/website/.gitignore +++ b/website/.gitignore @@ -1,6 +1,36 @@ -node_modules +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. -/.cache +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production /build -.env + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel .vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/website/.npmrc b/website/.npmrc deleted file mode 100644 index 165d6cf0..00000000 --- a/website/.npmrc +++ /dev/null @@ -1 +0,0 @@ -force=true \ No newline at end of file diff --git a/website/README.md b/website/README.md index 6d3efb51..b1d47025 100644 --- a/website/README.md +++ b/website/README.md @@ -1,36 +1,5 @@ -# Welcome to Remix! +# docs.page -- 📖 [Remix docs](https://remix.run/docs) +This is the website for the docs.page project, which hosts both the docs.page website and the documentation for projects. -## Development - -Run the dev server: - -```shellscript -npm run dev -``` - -## Deployment - -First, build your app for production: - -```sh -npm run build -``` - -Then run the app in production mode: - -```sh -npm start -``` - -Now you'll need to pick a host to deploy it to. - -### DIY - -If you're familiar with deploying Node applications, the built-in Remix app server is production-ready. - -Make sure to deploy the output of `npm run build` - -- `build/server` -- `build/client` +This project is a managed workspace using Bun - please see the contributing guide for more information and how to get started. \ No newline at end of file diff --git a/website/app/components/DocSearch.tsx b/website/app/components/DocSearch.tsx deleted file mode 100644 index e6daa512..00000000 --- a/website/app/components/DocSearch.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import docsearch from "@docsearch/js"; -import { forwardRef, useEffect, useImperativeHandle, useRef } from "react"; - -type Props = { - appId: string; - indexName: string; - apiKey: string; -}; - -export type DocSearchHandle = { - trigger(): void; -}; - -// This is a wrapper around the DocSearch library that allows us to trigger the search programmatically, -// without rendering the styled input the library provides. -const DocSearch = forwardRef( - ({ appId, indexName, apiKey }, ref) => { - // A ref for the parent container where DocSearch will be mounted. - const container = useRef(null); - const button = useRef(null); - - // Enable the parent component to trigger the search programmatically. - useImperativeHandle( - ref, - () => { - return { - trigger() { - if (button.current) { - button.current.click(); - } - }, - }; - }, - [], - ); - - useEffect(() => { - if (!container.current) return; - - // Apply the DocSearch logic to the hidden element. - docsearch({ - container: container.current, - appId, - indexName, - apiKey, - }); - - // Get the direct child (button) of the container. - const mounted = container.current.firstElementChild; - - // Store the button element in the ref. - if (mounted) { - button.current = mounted as HTMLButtonElement; - } - }, [apiKey, appId, indexName]); - - // Hide the element so we can trigger the search programmatically. - return
; - }, -); - -export default DocSearch; diff --git a/website/app/entry.client.tsx b/website/app/entry.client.tsx deleted file mode 100644 index 9cc7ae4e..00000000 --- a/website/app/entry.client.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { RemixBrowser } from "@remix-run/react"; -import { StrictMode, startTransition } from "react"; -import { hydrateRoot } from "react-dom/client"; -import type { DocsPageContext } from "~/context"; - -declare global { - interface Window { - __docsPage?: DocsPageContext; - } -} - -// A list of base domains which can run this app in production. -const DOMAINS = ["docs.page", "staging.docs.page"]; - -if (window.__docsPage) { - const hostname = window.location.hostname; - - // Check if the current hostname is a vanity domain (e.g. `:org.docs.page`). - const isVanityDomain = - hostname.includes(".docs.page") && !DOMAINS.includes(hostname); - - // It's a custom domain if it's not a vanity domain and it's not one of the base domains. - const isCustomDomain = !isVanityDomain && !DOMAINS.includes(hostname); - - if (isVanityDomain || isCustomDomain) { - window.__remixContext.url = window.location.pathname; - } - - // // const { owner, repository } = window.__docsPage; - - // // A vanity domain is a rewrite request. - // if (isVanityDomain) { - // // const basename = `/${owner}`; - - // // window.__remixContext.basename = basename; - - // // Remove the owner from the URL (since it's now part of the hostname). - // window.__remixContext.url = window.location.pathname; - - // console.log("Rewriting context for vanity domain: ", { - // basename: window.__remixContext.basename, - // url: window.__remixContext.url, - // }); - // } - // // A custom domain is a proxy request. - // else if (isCustomDomain) { - // // console.log("Custom domain detected: ", { hostname, owner, repository }); - // // const basename = `/${owner}/${repository}`; - - // // // Set the base name to the owner and repository (e.g. `/invertase/docs.page`). - // // // window.__remixContext.basename = ''; - - // // // // Replace the URL which includes the repository with the correct URL. - // // // // For example: `/invertase/docs.page/configuration` -> `/configuration`. - // // // window.__remixContext.url = '/invertase/docs.page/configuration'; - - // // console.log("Rewriting context for custom domain: ", { - // // basename: window.__remixContext.basename, - // // url: window.__remixContext.url, - // // }); - // } -} - -startTransition(() => { - hydrateRoot( - document, - - - , - ); -}); diff --git a/website/app/layouts/DocsLayout.tsx b/website/app/layouts/DocsLayout.tsx deleted file mode 100644 index 3b93242d..00000000 --- a/website/app/layouts/DocsLayout.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { useState } from "react"; -import { Content } from "~/components/Content"; -import { Edit } from "~/components/Edit"; -import { Footer } from "~/components/Footer"; -import { Header } from "~/components/Header"; -import { PreviousNext } from "~/components/PreviousNext"; -import { Scripts } from "~/components/Scripts"; -import { Sidebar } from "~/components/Sidebar"; -import { TableOfContents } from "~/components/TableOfContents"; -import { Tabs } from "~/components/Tabs"; -import { ThemeScripts } from "~/components/Theme"; -import { useTabs } from "~/context"; -import { cn } from "~/utils"; - -export function DocsLayout() { - const hasTabs = useTabs().length > 0; - const [sidebar, setSidebar] = useState(false); - - function toggleSidebar() { - setSidebar((prev) => { - const open = !prev; - - if (open) { - document.body.style.overflow = "hidden"; - } else { - document.body.style.overflow = ""; - } - - return open; - }); - } - - return ( - <> - - -
-
- -
-
-
- -
-
-
toggleSidebar()} - onKeyDown={() => toggleSidebar()} - /> -
-
- - - -
-
-
-
- -
-
-
-
- - ); -} diff --git a/website/app/meta.ts b/website/app/meta.ts deleted file mode 100644 index 205f07e3..00000000 --- a/website/app/meta.ts +++ /dev/null @@ -1,78 +0,0 @@ -import type { LinkDescriptor } from "@remix-run/node"; -import type { MetaDescriptor } from "@remix-run/react"; - -export function getMetadata(): MetaDescriptor[] { - const title = "docs.page | Ship documentation, like you ship code"; - const description = - "Publish beautiful online documentation instantly, from your code editor using markdown and a public GitHub repository."; - const image = "https://docs.page/_docs.page/social-preview.png"; - - return [ - { - title, - }, - { - name: "description", - content: description, - }, - { - property: "og:title", - content: title, - }, - { - property: "og:description", - content: description, - }, - { - property: "og:image", - content: image, - }, - { - name: "twitter:title", - content: title, - }, - { - name: "twitter:description", - content: description, - }, - { - name: "twitter:site", - content: "@invertaseio", - }, - { - name: "twitter:image", - content: image, - }, - ]; -} - -export function getLinkDescriptors(): LinkDescriptor[] { - return [ - { - rel: "apple-touch-icon", - sizes: "180x180", - href: "/_docs.page/favicon/apple-touch-icon.png", - }, - { - rel: "icon", - type: "image/png", - sizes: "32x32", - href: "/_docs.page/favicon/favicon-32x32.png", - }, - { - rel: "icon", - type: "image/png", - sizes: "16x16", - href: "/_docs.page/favicon/favicon-16x16.png", - }, - { - rel: "manifest", - href: "/_docs.page/favicon/site.webmanifest", - }, - { - rel: "mask-icon", - href: "/_docs.page/favicon/safari-pinned-tab.svg", - color: "#5bbad5", - }, - ]; -} diff --git a/website/app/root.tsx b/website/app/root.tsx deleted file mode 100644 index e67dec24..00000000 --- a/website/app/root.tsx +++ /dev/null @@ -1,168 +0,0 @@ -import type { LinksFunction } from "@remix-run/node"; -import { - Links, - Meta, - Outlet, - Scripts, - ScrollRestoration, - isRouteErrorResponse, - useFetchers, - useLoaderData, - useNavigation, - useOutletContext, - useRouteError, - useRouteLoaderData, -} from "@remix-run/react"; - -import NProgress from "nprogress"; -import nProgressStyles from "nprogress/nprogress.css?url"; -import { type ReactElement, useEffect, useMemo } from "react"; -import zoomStyles from "react-medium-image-zoom/dist/styles.css?url"; -import { ErrorLayout } from "~/layouts/ErrorLayout"; -import type { BundleErrorResponse } from "./api"; -import styles from "./styles.css?url"; -import type { SharedEnvironmentVariables } from "./utils"; - -NProgress.configure({ showSpinner: false }); - -export const links: LinksFunction = () => [ - { rel: "stylesheet", href: styles }, - { - rel: "stylesheet", - href: zoomStyles, - }, - { - rel: "stylesheet", - href: nProgressStyles, - }, -]; - -export const loader = () => { - return { - ENV: { - VERCEL: process.env.VERCEL, - VERCEL_ENV: process.env.VERCEL_ENV, - VERCEL_GIT_COMMIT_SHA: process.env.VERCEL_GIT_COMMIT_SHA, - } satisfies SharedEnvironmentVariables, - }; -}; - -export function Layout({ children }: { children: React.ReactNode }) { - const data = useRouteLoaderData("root"); - - return ( - - - - - - - - - - - - - - - - - `); - - return ( - <> - {scripts} - `); + + return ( + <> + + {title} + + + + + + + + + + + + {scripts} + `); - return ( - <> - {scripts} +
@@ -44,7 +33,7 @@ export default function GetStartedRoute() {
- + ); } @@ -68,7 +57,7 @@ function Install() { description="Add docs.page to your project" asset={ Terminal Command @@ -116,7 +105,7 @@ function AddContent() { description="Add markdown to a page" asset={ Markdown @@ -153,7 +142,7 @@ function PreviewDocs() { description="Preview your docs.page site" asset={ Markdown @@ -161,9 +150,9 @@ function PreviewDocs() { meta={

View your documentation locally before publishing it to the web using{" "} - + Local Preview - {" "} + {" "} mode.

} @@ -194,7 +183,7 @@ function PublishChanges() { description="Make your changes public" asset={ Markdown diff --git a/website/app/routes/_layout._index/Afilliation.tsx b/website/src/layouts/homepage/Affiliation.tsx similarity index 100% rename from website/app/routes/_layout._index/Afilliation.tsx rename to website/src/layouts/homepage/Affiliation.tsx diff --git a/website/app/routes/_layout._index/CallToAction.tsx b/website/src/layouts/homepage/CallToAction.tsx similarity index 94% rename from website/app/routes/_layout._index/CallToAction.tsx rename to website/src/layouts/homepage/CallToAction.tsx index 84732433..17e28d3f 100644 --- a/website/app/routes/_layout._index/CallToAction.tsx +++ b/website/src/layouts/homepage/CallToAction.tsx @@ -1,5 +1,5 @@ import { HandshakeIcon } from "lucide-react"; -import { Button } from "../../components/Button"; +import { Button } from "~/components/Button"; export function CallToAction() { return ( diff --git a/website/app/routes/_layout._index/Demo.tsx b/website/src/layouts/homepage/Demo.tsx similarity index 82% rename from website/app/routes/_layout._index/Demo.tsx rename to website/src/layouts/homepage/Demo.tsx index 057fae56..a6e44994 100644 --- a/website/app/routes/_layout._index/Demo.tsx +++ b/website/src/layouts/homepage/Demo.tsx @@ -14,7 +14,10 @@ export function Demo() { preload="metadata" className="w-full rounded-xl" > - +
diff --git a/website/app/routes/_layout._index/Features.tsx b/website/src/layouts/homepage/Features.tsx similarity index 99% rename from website/app/routes/_layout._index/Features.tsx rename to website/src/layouts/homepage/Features.tsx index 446c3708..13c350a7 100644 --- a/website/app/routes/_layout._index/Features.tsx +++ b/website/src/layouts/homepage/Features.tsx @@ -6,7 +6,6 @@ import { Grid2X2Icon, Heading1Icon, PencilIcon, - RefreshCcwDot, RefreshCcwDotIcon, SearchIcon, SwatchBookIcon, diff --git a/website/app/routes/_layout._index/Hero.tsx b/website/src/layouts/homepage/Hero.tsx similarity index 86% rename from website/app/routes/_layout._index/Hero.tsx rename to website/src/layouts/homepage/Hero.tsx index f253de3a..d45e5117 100644 --- a/website/app/routes/_layout._index/Hero.tsx +++ b/website/src/layouts/homepage/Hero.tsx @@ -1,4 +1,4 @@ -import { Button } from "../../components/Button"; +import { Button } from "~/components/Button"; export function Hero() { return ( @@ -17,12 +17,12 @@ export function Hero() {

-
-
diff --git a/website/app/routes/_layout._index/Platform.tsx b/website/src/layouts/homepage/Platform.tsx similarity index 89% rename from website/app/routes/_layout._index/Platform.tsx rename to website/src/layouts/homepage/Platform.tsx index 351fa60b..ddbaf6c5 100644 --- a/website/app/routes/_layout._index/Platform.tsx +++ b/website/src/layouts/homepage/Platform.tsx @@ -1,4 +1,4 @@ -import { BookTextIcon, LockIcon } from "lucide-react"; +import { BookTextIcon } from "lucide-react"; const ASSET_VERSION = 2; @@ -89,7 +89,7 @@ function PlatformCard(props: PlatformCardProps) { function Manage() { return ( Manage Docs as Code @@ -99,7 +99,7 @@ function Manage() { function BeautifulByDesign() { return ( Publish Instantly @@ -109,7 +109,7 @@ function BeautifulByDesign() { function Preview() { return ( Publish Instantly @@ -119,7 +119,7 @@ function Preview() { function Publish() { return ( Publish Instantly @@ -129,7 +129,7 @@ function Publish() { function Customize() { return ( Publish Instantly ); diff --git a/website/app/routes/_layout._index/Testimonials.tsx b/website/src/layouts/homepage/Testimonials.tsx similarity index 100% rename from website/app/routes/_layout._index/Testimonials.tsx rename to website/src/layouts/homepage/Testimonials.tsx diff --git a/website/app/routes/_layout._index/route.tsx b/website/src/layouts/homepage/index.tsx similarity index 58% rename from website/app/routes/_layout._index/route.tsx rename to website/src/layouts/homepage/index.tsx index c29d1383..3fd42cf1 100644 --- a/website/app/routes/_layout._index/route.tsx +++ b/website/src/layouts/homepage/index.tsx @@ -1,20 +1,18 @@ +import { HeroGradient } from "~/components/HeroGradient"; +import { Footer } from "~/layouts/Footer"; import { Header } from "~/layouts/Header"; -import { getLinkDescriptors, getMetadata } from "~/meta"; -import { Footer } from "../../layouts/Footer"; -import { HeroGradient } from "../../layouts/HeroGradient"; -import { Affiliation } from "./Afilliation"; +import { Site } from "~/layouts/Site"; + +import { Affiliation } from "./Affiliation"; import { CallToAction } from "./CallToAction"; import { Demo } from "./Demo"; import { Features } from "./Features"; import { Hero } from "./Hero"; import { Platform } from "./Platform"; -export const links = getLinkDescriptors; -export const meta = getMetadata; - -export default function Homepage() { +export function Homepage() { return ( - <> +
@@ -25,6 +23,6 @@ export default function Homepage() { {/* */}