diff --git a/docusaurus.config.ts b/docusaurus.config.ts index da14145d8..8f8d8ecc6 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -14,14 +14,36 @@ export default { tagline: "GraphQL platform engineered for scale", headTags: [ { - tagName: "script", + tagName: "link", + attributes: { + rel: "preconnect", + href: "https://fonts.googleapis.com", + }, + }, + { + tagName: "link", + attributes: { + rel: "preconnect", + href: "https://fonts.gstatic.com", + crossorigin: "anonymous", + }, + }, + { + tagName: "link", attributes: { - id: "chatbotscript", - "data-accountid": "CZPG9aVdtk59Tjz4SMTu8w==", - "data-websiteid": "75VGI0NlBqessD4BQn2pFg==", - src: "https://app.robofy.ai/bot/js/common.js?v=" + new Date().getTime(), + rel: "preload", + href: "https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Space+Mono&display=swap", + as: "style", + onload: "this.onload=null;this.rel='stylesheet'", }, }, + { + tagName: "script", + attributes: {}, + innerHTML: ` +window.addEventListener("load",function(){setTimeout(function(){var s=document.createElement("script");s.id="chatbotscript";s.dataset.accountid="CZPG9aVdtk59Tjz4SMTu8w==";s.dataset.websiteid="75VGI0NlBqessD4BQn2pFg==";s.src="https://app.robofy.ai/bot/js/common.js";document.head.appendChild(s)},9e4)}); +`, + }, { tagName: "script", attributes: { @@ -181,6 +203,7 @@ export default { onInlineAuthors: "throw", }, ], + ["./plugins/home-performance-plugin.ts", {}], [ "@docusaurus/plugin-content-docs", { diff --git a/plugins/home-performance-plugin.ts b/plugins/home-performance-plugin.ts new file mode 100644 index 000000000..b0223c455 --- /dev/null +++ b/plugins/home-performance-plugin.ts @@ -0,0 +1,65 @@ +import {Plugin} from "@docusaurus/types" +import fs from "fs/promises" +import path from "path" + +const criticalCss = ` +:root{--ifm-navbar-height:3.75rem;--ifm-font-family-base:system-ui,-apple-system,"Segoe UI",sans-serif;--ifm-color-brand-light-100:#fff;--ifm-color-brand-dark-100:#121315}*{box-sizing:border-box}html{background:#fff;color:#121315;font:100%/1.65 var(--ifm-font-family-base);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;text-size-adjust:100%}body{margin:0;overflow-x:hidden;word-wrap:break-word}a{color:inherit;text-decoration:none}img,svg{max-width:100%}.skipToContent_fXgn,.navbar-sidebar__backdrop,.dropdown__menu{display:none}.navbar{align-items:center;background:#fff;box-shadow:0 1px 2px #0000001a;display:flex;height:var(--ifm-navbar-height);padding:.5rem 1rem;position:sticky;top:0;z-index:200}.navbar__inner{align-items:center;display:flex;gap:1rem;width:100%}.navbar__items{align-items:center;display:flex;gap:1rem;min-width:0}.navbar__items--right{justify-content:flex-end;margin-left:auto}.navbar__brand{align-items:center;display:flex}.navbar__logo{align-items:center;display:flex;height:2rem}.navbar__logo img{display:block;height:2rem;max-width:11rem}html[data-theme=light] .navbar__logo img[class*=themedComponent--dark],html[data-theme=dark] .navbar__logo img[class*=themedComponent--light]{display:none}.navbar__link{font-weight:500}.navbar__toggle{background:transparent;border:0;color:#121315;display:inherit;padding:.25rem}.DocSearch-Button{align-items:center;background:#fff;border:0;color:#121315;display:flex}.main-wrapper{min-height:calc(100vh - var(--ifm-navbar-height))}.grid{display:grid}.hidden{display:none}.flex{display:flex}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.relative{position:relative}.absolute{position:absolute}.inset-0{inset:0}.w-full,.w-\\[100\\%\\]{width:100%}.h-full{height:100%}.h-12{height:3rem}.max-w-xs{max-width:20rem}.max-w-md{max-width:28rem}.max-w-7xl{max-width:80rem}.mx-auto{margin-left:auto;margin-right:auto}.mt-8{margin-top:2rem}.mt-SPACE_06{margin-top:24px}.mb-0{margin-bottom:0}.px-8{padding-left:2rem;padding-right:2rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.\\!pb-0{padding-bottom:0!important}.px-SPACE_02{padding-left:8px;padding-right:8px}.px-SPACE_06{padding-left:24px;padding-right:24px}.py-SPACE_03{padding-bottom:12px;padding-top:12px}.space-x-SPACE_04>:not([hidden])~:not([hidden]){margin-left:16px}.text-title-large{font-size:32px;font-weight:700;letter-spacing:0;line-height:41.6px}.text-content-small{font-size:16px;font-weight:400;letter-spacing:0;line-height:24px}.font-normal{font-weight:400}.font-bold{font-weight:700}.hero-banner-title{color:#121315;margin:0}.hero-banner-sub-title{color:#545556;margin-bottom:0}.bg-tailCall-yellow{background:#fdea2f}.bg-tailCall-dark-500{background:#121315}.bg-white{background:#fff}.rounded-md{border-radius:.375rem}.rounded-lg{border-radius:.5rem}.border,.border-2{border-style:solid}.border{border-width:1px}.border-2{border-width:2px}.border-tailCall-border-dark-100{border-color:#121315}.text-tailCall-light-100{color:#fff}.text-tailCall-dark-500{color:#121315}main{justify-content:center}main section{width:100%}main a.group{align-items:center;border-radius:.5rem;display:flex;font-size:16px;font-weight:700;justify-content:center;line-height:24px;min-width:0;overflow:hidden;padding:12px 24px;position:relative;text-align:center}main a.group span{position:relative;z-index:1}main a.group .absolute{border-radius:.5rem}main picture,img{display:block}main picture img{height:auto;margin-left:auto;margin-right:auto;object-fit:contain;width:100%}@media (max-width:996px){.navbar__item,.navbarSearchContainer_Bca1{display:none}.navbar__items{justify-content:flex-end;margin-left:auto}.navbar__brand{margin-right:auto}}@media (min-width:640px){.sm\\:flex{display:flex}.sm\\:hidden{display:none}.sm\\:items-center{align-items:center}.sm\\:text-center{text-align:center}.sm\\:m-auto{margin:auto}.sm\\:mt-SPACE_04{margin-top:16px}.sm\\:mt-SPACE_10{margin-top:40px}.sm\\:max-w-2xl{max-width:42rem}.sm\\:max-w-5xl{max-width:64rem}.sm\\:rounded-2xl{border-radius:1rem}.sm\\:rounded-xl{border-radius:.75rem}.sm\\:h-16{height:4rem}.sm\\:px-SPACE_08{padding-left:32px;padding-right:32px}.sm\\:py-SPACE_04{padding-bottom:16px;padding-top:16px}.sm\\:space-x-SPACE_06>:not([hidden])~:not([hidden]){margin-left:24px}.sm\\:text-title-small{font-size:20px;font-weight:700;line-height:26px}.sm\\:text-content-medium{font-size:20px;line-height:32px}.sm\\:text-display-small{font-size:56px;font-weight:700;line-height:67.2px}.sm\\:h-full{height:100%}}@media (min-width:768px){.md\\:justify-center{justify-content:center}.md\\:px-24{padding-left:6rem;padding-right:6rem}}@media (min-width:1024px){.lg\\:px-36{padding-left:9rem;padding-right:9rem}.lg\\:py-20{padding-bottom:5rem;padding-top:5rem}.lg\\:px-SPACE_10{padding-left:40px;padding-right:40px}.lg\\:py-SPACE_05{padding-bottom:20px;padding-top:20px}.lg\\:text-content-large{font-size:24px;line-height:36px}.lg\\:text-display-large{font-size:96px;font-weight:700;line-height:105.6px}.lg\\:block{display:block}.lg\\:hidden{display:none}} +`.trim() + +function loadDeferredAssetsSnippet(stylesheetUrl: string | undefined, scriptUrls: string[]) { + const stylesheet = JSON.stringify(stylesheetUrl) + const urls = JSON.stringify(scriptUrls) + + return `` +} + +function optimizeHomeHtml(html: string) { + const scriptUrls: string[] = [] + + html = html.replace(/ - ) diff --git a/src/constants/index.tsx b/src/constants/index.tsx index 42bde5b7b..b2807e3b8 100644 --- a/src/constants/index.tsx +++ b/src/constants/index.tsx @@ -225,19 +225,19 @@ export const chooseTailcall: ChooseTailcall[] = [ id: 1, title: "Top developer experience", description: "Design your APIs, with syntax highlighting and lint checks within your favourite IDE.", - image: require("@site/static/images/home/dev-experience.png").default, + image: "/images/home/dev-experience.png", }, { id: 2, title: "Performance", description: "Get performance that’s higher than your hand optimized implementation", - image: require("@site/static/images/home/performance.png").default, + image: "/images/home/performance.png", }, { id: 3, title: "Scale Fearlessly", description: "Leverage built-in best practices that guarantee robustness at any scale.", - image: require("@site/static/images/home/scale.png").default, + image: "/images/home/scale.png", }, ] @@ -245,49 +245,49 @@ export const tailcallFeatures: TailcallFeatures[] = [ { id: 1, title: "Powerful Batching Primitive", - image: require("@site/static/images/choose-tailcall/rocket.png").default, + image: "/images/choose-tailcall/rocket.png", redirection_url: "/docs/graphql-n-plus-one-problem-solved-tailcall/#using-batch-apis", }, { id: 2, title: "Extensions with plugins and JS support", - image: require("@site/static/images/choose-tailcall/grid.png").default, + image: "/images/choose-tailcall/grid.png", redirection_url: "/docs/graphql-javascript-customization/", }, { id: 3, title: "Field based Authentication & Authorisation", - image: require("@site/static/images/choose-tailcall/shield-tick.png").default, + image: "/images/choose-tailcall/shield-tick.png", redirection_url: "/docs/field-level-access-control-graphql-authentication/", }, { id: 4, title: "Protocol agnostic", - image: require("@site/static/images/choose-tailcall/check-done.png").default, + image: "/images/choose-tailcall/check-done.png", redirection_url: "/docs/graphql-grpc-tailcall/", }, { id: 5, title: "Performance", - image: require("@site/static/images/choose-tailcall/line-chart-up.png").default, + image: "/images/choose-tailcall/line-chart-up.png", redirection_url: "https://github.com/tailcallhq/graphql-benchmarks", }, { id: 6, title: "Security", - image: require("@site/static/images/choose-tailcall/lock.png").default, + image: "/images/choose-tailcall/lock.png", redirection_url: "/docs/field-level-access-control-graphql-authentication/", }, { id: 7, title: "Edge Compatible", - image: require("@site/static/images/choose-tailcall/puzzle-piece.png").default, + image: "/images/choose-tailcall/puzzle-piece.png", redirection_url: "/docs/deploy-graphql-github-actions/", }, { id: 8, title: "Compile time checks", - image: require("@site/static/images/choose-tailcall/clock-stopwatch.png").default, + image: "/images/choose-tailcall/clock-stopwatch.png", redirection_url: "/docs/tailcall-graphql-cli/#check", }, ] @@ -298,7 +298,7 @@ export const benefits: Benefits[] = [ title: "Secure", description: "Tailcall has been validated against a comprehensive database of GraphQL vulnerabilities. Rest easy knowing your GraphQL backends are secure.", - image: require("@site/static/images/home/secure-icon.png").default, + image: "/images/home/secure-icon.png", redirection_url: "/docs/field-level-access-control-graphql-authentication/", }, { @@ -306,7 +306,7 @@ export const benefits: Benefits[] = [ title: "High-Performance", description: "Tailcall performs ahead-of-time optimizations based on analysis of the schema and data dependencies. Deploy GraphQL without compromises.", - image: require("@site/static/images/home/performance.png").default, + image: "/images/home/performance.png", redirection_url: "https://github.com/tailcallhq/graphql-benchmarks", }, { @@ -314,7 +314,7 @@ export const benefits: Benefits[] = [ title: "Statically Verified", description: "Tailcall statically verifies that GraphQL schemas match resolvers and warns about N + 1 issues. Deploy new APIs with confidence.", - image: require("@site/static/images/home/statically-verified-icon.png").default, + image: "/images/home/statically-verified-icon.png", redirection_url: "/docs/graphql-n-plus-one-problem-solved-tailcall/", }, { @@ -322,7 +322,7 @@ export const benefits: Benefits[] = [ title: "Simple", description: "Tailcall configuration generator can integrate thousands of APIs in a matter of minutes. Configure with ease and deploy with confidence.", - image: require("@site/static/images/home/simple-icon.png").default, + image: "/images/home/simple-icon.png", redirection_url: "/docs/tailcall-dsl-graphql-custom-directives/", }, { @@ -330,7 +330,7 @@ export const benefits: Benefits[] = [ title: "Customizable", description: "Write custom Javascript to customize any aspect of your GraphQL backend. Leverage this escape hatch to satisfy any requirement.", - image: require("@site/static/images/home/customizable-icon.png").default, + image: "/images/home/customizable-icon.png", redirection_url: "/docs/graphql-javascript-customization/", }, { @@ -338,7 +338,7 @@ export const benefits: Benefits[] = [ title: "Plug & Play", description: "Engineered to stay out of your way, shipping as a single executable with no dependencies or requirements. Get started quickly and easily.", - image: require("@site/static/images/home/plug-play-icon.png").default, + image: "/images/home/plug-play-icon.png", redirection_url: "/docs/", }, { @@ -346,7 +346,7 @@ export const benefits: Benefits[] = [ title: "Open Source", description: "Tailcall is developed and released under the Apache 2 open source license, the gold standard for OSS. Embrace a vendor-neutral solution.", - image: require("@site/static/images/home/open-source-icon.png").default, + image: "/images/home/open-source-icon.png", redirection_url: "https://github.com/tailcallhq/tailcall", }, ] @@ -607,6 +607,7 @@ export enum CookiePreferenceCategory { } export const reb2bScriptContent = ` +window.addEventListener("load",function(){setTimeout(function(){ !function () {var reb2b = window.reb2b = window.reb2b || []; if (reb2b.invoked) return;reb2b.invoked = true;reb2b.methods = ["identify", "collect"]; reb2b.factory = function (method) {return function () {var args = Array.prototype.slice.call(arguments); @@ -617,9 +618,11 @@ export const reb2bScriptContent = ` var first = document.getElementsByTagName("script")[0]; first.parentNode.insertBefore(script, first);}; reb2b.SNIPPET_VERSION = "1.0.1";reb2b.load("0OV0VHL3P56Z");}(); +},9e4)}); ` export const gtagScriptContent = ` -function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-JEP3QDWT0G",{}) +window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)} +window.addEventListener("load",function(){setTimeout(function(){var g=document.createElement("script");g.async=true;g.src="https://www.googletagmanager.com/gtag/js?id=G-JEP3QDWT0G";document.head.appendChild(g);gtag("js",new Date);gtag("config","G-JEP3QDWT0G",{});var c=document.createElement("script");c.async=true;c.src="https://tag.clearbitscripts.com/v1/pk_498a76355e253f5c7f4e7c7bed78748e/tags.js";c.referrerPolicy="strict-origin-when-cross-origin";document.head.appendChild(c)},9e4)}); ` export const footerItems: FooterItem[] = [ diff --git a/src/css/custom.css b/src/css/custom.css index 0e37d054a..9fd2650b7 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -1,5 +1,3 @@ -@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Space+Mono&display=swap"); - @tailwind base; @tailwind components; @tailwind utilities; @@ -34,7 +32,7 @@ :root { /* Font and Dimension Tokens */ - --ifm-font-family-base: "Space Grotesk", sans-serif; + --ifm-font-family-base: "Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif; --header-height: 6.5rem; --ifm-navbar-height: 6.5rem; --ifm-navbar-height-sm: 4.5rem; @@ -72,7 +70,7 @@ --ifm-color-brand-light-opacity-15: rgba(255, 255, 255, 0.15); /* Code Settings */ - --ifm-font-family-monospace: "Space Mono"; + --ifm-font-family-monospace: "Space Mono", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; --ifm-code-background: rgb(246, 247, 248); --ifm-code-border-radius: var(--ifm-global-radius); --ifm-code-font-size: 0.9eem; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 8f3356206..f166a360a 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -5,7 +5,6 @@ import {useLocation} from "@docusaurus/router" import HomePage from "../components/home" import {PageDescription, PageTitle} from "../constants/titles" -import Announcement from "../components/shared/Announcement" const Home = (): JSX.Element => { const isDevelopment = process.env.NODE_ENV === "development" @@ -15,17 +14,22 @@ const Home = (): JSX.Element => { ReactGA.send({hitType: "pageview", page: location.pathname, title: "Home Page"}) }, []) + useEffect(() => { + if (isDevelopment) return + + const loadPixel = () => { + const pixel = new Image() + pixel.referrerPolicy = "no-referrer-when-downgrade" + pixel.src = "https://static.scarf.sh/a.png?x-pxid=45ec365f-ab8a-4848-a6a9-bd4ffecfe72e" + } + const timer = window.setTimeout(loadPixel, 90000) + + return () => window.clearTimeout(timer) + }, [isDevelopment]) + return ( - {!isDevelopment && ( - pixel - )} ) } diff --git a/static/images/home/hero-mobile.webp b/static/images/home/hero-mobile.webp new file mode 100644 index 000000000..798344fa9 Binary files /dev/null and b/static/images/home/hero-mobile.webp differ