diff --git a/website/next.config.js b/website/next.config.js index 60499530268c4..d50b4b743d9b1 100644 --- a/website/next.config.js +++ b/website/next.config.js @@ -6,6 +6,9 @@ export default withGuildDocs({ eslint: { ignoreDuringBuilds: true, }, + nextraConfig: { + autoImportThemeStyle: false, + }, redirects: () => Object.entries({ '/api': '/docs', diff --git a/website/package.json b/website/package.json index 16564d6ee4854..34f1270250fcb 100644 --- a/website/package.json +++ b/website/package.json @@ -10,7 +10,7 @@ "start": "next start" }, "dependencies": { - "@theguild/components": "^7.0.0", + "@theguild/components": "^7.6.0", "next": "^15.0.0", "next-sitemap": "^4.2.3", "react": "^19.0.0", diff --git a/website/public/assets/graphql-logo.svg b/website/public/assets/graphql-logo.svg deleted file mode 100644 index b568a10410dfd..0000000000000 --- a/website/public/assets/graphql-logo.svg +++ /dev/null @@ -1,134 +0,0 @@ - - - - diff --git a/website/public/assets/mesh-diagram.svg b/website/public/assets/mesh-diagram.svg deleted file mode 100644 index 05cf9135a4559..0000000000000 --- a/website/public/assets/mesh-diagram.svg +++ /dev/null @@ -1,330 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/public/assets/mesh-example.png b/website/public/assets/mesh-example.png deleted file mode 100644 index 0746c55ffb5d3..0000000000000 Binary files a/website/public/assets/mesh-example.png and /dev/null differ diff --git a/website/public/assets/open-source.svg b/website/public/assets/open-source.svg deleted file mode 100644 index 62362ebe42759..0000000000000 --- a/website/public/assets/open-source.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - diff --git a/website/public/codesandbox-iframe.html b/website/public/codesandbox-iframe.html new file mode 100644 index 0000000000000..1e4fe57f87660 --- /dev/null +++ b/website/public/codesandbox-iframe.html @@ -0,0 +1,51 @@ + + + + + + GraphQL Mesh Example + + + + + + + + diff --git a/website/public/favicon.ico b/website/public/favicon.ico deleted file mode 100644 index d17615c39b27d..0000000000000 Binary files a/website/public/favicon.ico and /dev/null differ diff --git a/website/public/favicon.svg b/website/public/favicon.svg new file mode 100644 index 0000000000000..1f6baf3883f43 --- /dev/null +++ b/website/public/favicon.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/website/src/components/comparison-table/index.tsx b/website/src/components/comparison-table/index.tsx index 0a9ea6e503e0e..2147232c6ee3b 100644 --- a/website/src/components/comparison-table/index.tsx +++ b/website/src/components/comparison-table/index.tsx @@ -90,17 +90,21 @@ const headers = Object.keys(data[0]); export interface ComparisonTableProps extends React.HTMLAttributes {} export function ComparisonTable({ children, className, ...rest }: ComparisonTableProps) { return ( -
-
+
+
Consider switching from other tools? -

+

Learn the differences between Mesh, Apollo Federation, Hasura and GraphQL Tools

-
- + {/* this is focusable (by default) because a keyboard user will scroll through the overflowing table with arrows */} +
+
{headers.map(header => ( diff --git a/website/src/components/datasources-illustration/index.tsx b/website/src/components/datasources-illustration/index.tsx new file mode 100644 index 0000000000000..1856cead3fb59 --- /dev/null +++ b/website/src/components/datasources-illustration/index.tsx @@ -0,0 +1,160 @@ +import { ReactNode } from 'react'; +import { cn, Heading, PRODUCTS, Stud } from '@theguild/components'; + +export function DatasourcesIllustration({ className }: { className?: string }) { + return ( +
+
+ + Connect datasources + +

+ Transform non-GraphQL services into GraphQL-ready interfaces with Mesh, enhancing API + consistency. +

+
    + {[ + { + icon: , + text: 'Automate the creation of type-safe GraphQL APIs from any data source, ensuring reliability and developer efficiency.', + }, + { + icon: , + text: 'Enhance data sources by integrating additional data with full type safety, using Mesh.', + }, + { + icon: , + text: 'Extend the capabilities of your schema with Mesh by mocking, caching, and transforming data seamlessly.', + }, + ].map(({ icon, text }) => ( +
  • + {icon} +

    {text}

    +
  • + ))} +
+
+
+ +
+
+ ); +} + +function Illustration({ className }: { className?: string }) { + return ( +
+ Mobile App + Web App + Node.js Client + + + +
+
+ +
GraphQL Mesh
+
+ + + + + + + + +
+ + + + Books Rest API + + Authors gRPC API + + + Stores GraphQL API + +
+ ); +} + +function SmallNode({ children, className }: { children: ReactNode; className?: string }) { + return ( +
+
+ {children} +
+
+ ); +} + +function Diagonal({ + variant, + className, +}: { + variant: 'left' | 'middle' | 'right'; + className?: string; +}) { + if (variant === 'middle') { + return
; + } + + return ( + + + + ); +} + +function TiltMeterIcon() { + return ( + + + + ); +} + +function PaperclipIcon() { + return ( + + + + ); +} + +function ScanLine() { + return ( + + + + ); +} diff --git a/website/src/components/datasources-list-section.tsx b/website/src/components/datasources-list-section.tsx new file mode 100644 index 0000000000000..291bda4e9e703 --- /dev/null +++ b/website/src/components/datasources-list-section.tsx @@ -0,0 +1,111 @@ +import { Fragment } from 'react'; +import { + Anchor, + ArrowIcon, + cn, + DecorationIsolation, + Heading, + MeshIcon, +} from '@theguild/components'; + +const datasources = [ + { + name: 'GraphQL', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/graphql', + }, + { + name: 'OpenAPI', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/openapi', + }, + { + name: 'gRPC', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/grpc', + }, + { + name: 'JSON Schema', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/json-schema', + }, + { + name: 'SOAP', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/soap', + }, + { + name: 'OData', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/odata', + }, + { + name: 'Thrift', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/thrift', + }, + { + name: 'SQLite', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/sqlite', + }, + { + name: 'MySQL', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/mysql', + }, + { + name: 'Neo4j', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/neo4j', + }, + { + name: 'PostgreSQL', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/postgres', + }, + { + name: 'MongoDB', + href: 'https://the-guild.dev/graphql/mesh/v1/source-handlers/mongodb', + }, +]; + +export function DatasourcesListSection(props: React.HTMLAttributes) { + return ( +
+ + + + + Query anything + +

+ Deploy Mesh across any JavaScript environment, powered by its versatile Fetch API + compatibility. +

+
    + {datasources.map((datasource, i) => ( + + {i === Math.floor(datasources.length / 2) + 1 && ( +
  • + )} +
  • + + {datasource.name} + + +
  • +
    + ))} +
+
+ ); +} diff --git a/website/src/components/examples-sandbox.tsx b/website/src/components/examples-sandbox.tsx new file mode 100644 index 0000000000000..f742791ff48e3 --- /dev/null +++ b/website/src/components/examples-sandbox.tsx @@ -0,0 +1,144 @@ +'use client'; + +import { useEffect, useRef, useState } from 'react'; +import { useRouter } from 'next/router'; +import { CaretSlimIcon, cn } from '@theguild/components'; + +export const EXAMPLES = { + OpenAPI: { + 'JavaScript Wiki': 'openapi-javascript-wiki', + 'Location Weather': 'openapi-location-weather', + YouTrack: 'openapi-youtrack', + Stripe: 'openapi-stripe', + StackExchange: 'openapi-stackexchange', + 'WeatherBit on React App': 'openapi-react-weatherbit', + 'NextJS with Apollo': 'nextjs-apollo-example', + }, + 'JSON Schema': { + 'Fake API': 'json-schema-example', + 'Covid-19 Statistics': 'json-schema-covid', + 'Subscriptions, Webhooks & Live Queries': 'json-schema-subscriptions', + }, + OData: { + TripPin: 'odata-trippin', + 'Microsoft Graph': 'odata-microsoft', + }, + SOAP: { + 'Country Info': 'soap-country-info', + }, + MySQL: { + Rfam: 'mysql-rfam', + }, + SQLite: { + Chinook: 'sqlite-chinook', + }, + 'Apollo Federation': { + 'Apollo Federation Example': 'federation-example', + }, + 'Apache Thrift': { + Calculator: 'thrift-calculator', + }, + gRPC: { + 'Movies Example': 'grpc-example', + }, + Neo4J: { + 'Movies Example': 'neo4j-example', + }, +}; + +/** + * These options won't work if the Sandbox is a DevBox (not Legacy). + * @see https://codesandbox.io/docs/learn/sandboxes/embedding + */ +const CODESANDBOX_OPTIONS = { + codemirror: '1', + hidedevtools: '1', + hidenavigation: '1', + view: 'editor', + module: '%2F.meshrc.yml', +}; + +export interface ExamplesSandboxProps extends React.HTMLAttributes { + lazy?: boolean; + border?: boolean; +} + +export function ExamplesSandbox({ lazy = false, border = false, ...rest }: ExamplesSandboxProps) { + const [exampleDir, setExampleDir] = useState('json-schema-example'); + const [isVisible, setIsVisible] = useState(!lazy); + const containerRef = useRef(null!); + + useEffect(() => { + if (isVisible) return; + + const observer = new IntersectionObserver( + entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + setIsVisible(true); + observer.disconnect(); + } + }); + }, + { + rootMargin: '100px', + threshold: 0.1, + }, + ); + + observer.observe(containerRef.current); + + return () => observer.disconnect(); + }, []); + + const { basePath } = useRouter(); + + const iframeSrc = `${basePath}/codesandbox-iframe.html?example=${exampleDir}`; + + return ( +
+
+ Choose Live Example: + +
+ +
+
+
+ {isVisible && ( +