diff --git a/babel.config.cjs b/babel.config.cjs
new file mode 100644
index 0000000..47fe5c9
--- /dev/null
+++ b/babel.config.cjs
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
+}
diff --git a/blog/2023-07-03-new-frontend.md b/blog/2023-07-03-new-frontend.md
new file mode 100644
index 0000000..cb19c30
--- /dev/null
+++ b/blog/2023-07-03-new-frontend.md
@@ -0,0 +1,21 @@
+---
+slug: new-frontend
+title: We launched a new frontend
+authors:
+ name: chris48s
+ title: Shields.io Core Team
+ url: https://github.com/chris48s
+ image_url: https://avatars.githubusercontent.com/u/6025893
+tags: []
+---
+
+Alongside the general visual refresh and improvements to look and feel, our new frontend has allowed us to address a number of long-standing feature requests and enhancements:
+
+- Clearer and more discoverable documentation for our [static](https://shields.io/badges/static-badge), dynamic [json](https://shields.io/badges/dynamic-json-badge)/[xml](https://shields.io/badges/dynamic-xml-badge)/[yaml](https://shields.io/badges/dynamic-yaml-badge) and [endpoint](https://shields.io/badges/endpoint-badge) badges
+- Improved badge builder interface, with all optional query parameters included in the builder for each badge
+- Each badge now has its own documentation page, which we can link to. e.g: [https://shields.io/badges/discord](https://shields.io/badges/discord)
+- Light/dark mode themes
+- Improved search
+- Documentation for individual path and query parameters
+
+The new site also comes with big maintenance benefits for the core team. We rely heavily on [docusaurus](https://docusaurus.io/), [docusaurus-openapi](https://github.com/cloud-annotations/docusaurus-openapi), and [docusaurus-search-local](https://github.com/easyops-cn/docusaurus-search-local). This moves us to a mostly declarative setup, massively reducing the amount of custom frontend code we maintain ourselves.
diff --git a/blog/2023-07-29-tag-filter.md b/blog/2023-07-29-tag-filter.md
new file mode 100644
index 0000000..88abd32
--- /dev/null
+++ b/blog/2023-07-29-tag-filter.md
@@ -0,0 +1,19 @@
+---
+slug: tag-filter
+title: Applying filters to GitHub Tag and Release badges
+authors:
+ name: chris48s
+ title: Shields.io Core Team
+ url: https://github.com/chris48s
+ image_url: https://avatars.githubusercontent.com/u/6025893
+tags: []
+---
+
+We recently shipped a feature which allows you to pass an arbitrary filter to the GitHub tag and release badges. The `filter` param can be used to apply a filter to the project's tag or release names before selecting the latest from the list. Two constructs are available: `*` is a wildcard matching zero or more characters, and if the pattern starts with a `!`, the whole pattern is negated.
+
+To give an example of how this might be useful, we create two types of tags on our GitHub repo: https://github.com/badges/shields/tags There are tags in the format `major.minor.patch` which correspond to our [NPM package releases](https://www.npmjs.com/package/badge-maker?activeTab=versions) and tags in the format `server-YYYY-MM-DD` that correspond to our [docker snapshot releases](https://registry.hub.docker.com/r/shieldsio/shields/tags?page=1&ordering=last_updated).
+
+In our case, this would allow us to make a badge that applies the filter `!server-*` to filter out the snapshot tags and just select the latest package tag.
+
+- ![tag badge without filter](https://img.shields.io/github/v/tag/badges/shields) - https://img.shields.io/github/v/tag/badges/shields
+- ![tag badge with filter](https://img.shields.io/github/v/tag/badges/shields?filter=%21server-%2A) - https://img.shields.io/github/v/tag/badges/shields?filter=%21server-%2A
diff --git a/blog/2023-11-29-simpleicons10.md b/blog/2023-11-29-simpleicons10.md
new file mode 100644
index 0000000..2d49227
--- /dev/null
+++ b/blog/2023-11-29-simpleicons10.md
@@ -0,0 +1,14 @@
+---
+slug: simple-icons-10
+title: Simple Icons 10
+authors:
+ name: chris48s
+ title: Shields.io Core Team
+ url: https://github.com/chris48s
+ image_url: https://avatars.githubusercontent.com/u/6025893
+tags: []
+---
+
+Logos on Shields.io are provided by SimpleIcons. We've recently upgraded to SimpleIcons 10. This release removes 45 icons. A full list of the removals can be found in the [release notes](https://github.com/simple-icons/simple-icons/releases/tag/10.0.0).
+
+Please remember that we are just consumers of SimpleIcons. Decisions about changes and removals are made by the [SimpleIcons](https://github.com/simple-icons/simple-icons) project.
diff --git a/blog/2024-01-13-simpleicons11.md b/blog/2024-01-13-simpleicons11.md
new file mode 100644
index 0000000..08daadc
--- /dev/null
+++ b/blog/2024-01-13-simpleicons11.md
@@ -0,0 +1,21 @@
+---
+slug: simple-icons-11
+title: Simple Icons 11
+authors:
+ name: chris48s
+ title: Shields.io Core Team
+ url: https://github.com/chris48s
+ image_url: https://avatars.githubusercontent.com/u/6025893
+tags: []
+---
+
+Logos on Shields.io are provided by SimpleIcons. We've recently upgraded to SimpleIcons 11. This release removes the following 4 icons:
+
+- Babylon.js
+- Hulu
+- Pepsi
+- Uno
+
+More details can be found in the [release notes](https://github.com/simple-icons/simple-icons/releases/tag/11.0.0).
+
+Please remember that we are just consumers of SimpleIcons. Decisions about changes and removals are made by the [SimpleIcons](https://github.com/simple-icons/simple-icons) project.
diff --git a/categories/.gitkeep b/categories/.gitkeep
new file mode 100644
index 0000000..473a0f4
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..3f6c657
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,13 @@
+---
+sidebar_position: 1
+---
+
+# Intro
+
+Shields.io is a service for concise, consistent, and legible badges, which can easily be included in GitHub readmes or any other web page. The service supports dozens of continuous integration services, package registries, distributions, app stores, social networks, code coverage services, and code analysis services. It is used by some of the world's most popular open-source projects.
+
+Browse a [complete list of badges](/badges) and locate a particular badge by using the search bar or by browsing the categories.
+
+Use the builder to fill in required path parameters for that badge type (like your username or repo) and optionally customize (label, colors etc.). And it's ready for use! Copy your badge url or code snippet, which can then be added to places like your GitHub readme files or other web pages.
+
+![screenshot of the badge builder](/img/builder.png)
diff --git a/docs/logos.md b/docs/logos.md
new file mode 100644
index 0000000..4df5400
--- /dev/null
+++ b/docs/logos.md
@@ -0,0 +1,37 @@
+---
+sidebar_position: 2
+---
+
+# Logos
+
+## SimpleIcons
+
+We support a wide range of logos via [SimpleIcons](https://simpleicons.org/). All simple-icons are referenced using icon slugs. e.g:
+
+![](https://img.shields.io/npm/v/npm.svg?logo=nodedotjs) - https://img.shields.io/npm/v/npm.svg?logo=nodedotjs
+
+You can click the icon title on simple-icons to copy the slug or they can be found in the slugs.md file in the simple-icons repository. NB - the Simple Icons site and slugs.md page may at times contain new icons that haven't yet been pulled into Shields.io yet. More information on how and when we incorporate icon updates can be found [here](https://github.com/badges/shields/discussions/5369).
+
+## Shields logos
+
+We also maintain a small number of custom logos for a handful of services: https://github.com/badges/shields/tree/master/logo They can also be referenced by name and take preference to SimpleIcons e.g:
+
+![](https://img.shields.io/npm/v/npm.svg?logo=npm) - https://img.shields.io/npm/v/npm.svg?logo=npm
+
+## Custom Logos
+
+Any custom logo can be passed in a URL parameter by base64 encoding it. e.g:
+
+![](https://img.shields.io/badge/play-station-blue.svg?logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEiIHdpZHRoPSI2MDAiIGhlaWdodD0iNjAwIj48cGF0aCBkPSJNMTI5IDExMWMtNTUgNC05MyA2Ni05MyA3OEwwIDM5OGMtMiA3MCAzNiA5MiA2OSA5MWgxYzc5IDAgODctNTcgMTMwLTEyOGgyMDFjNDMgNzEgNTAgMTI4IDEyOSAxMjhoMWMzMyAxIDcxLTIxIDY5LTkxbC0zNi0yMDljMC0xMi00MC03OC05OC03OGgtMTBjLTYzIDAtOTIgMzUtOTIgNDJIMjM2YzAtNy0yOS00Mi05Mi00MmgtMTV6IiBmaWxsPSIjZmZmIi8+PC9zdmc+) - https://img.shields.io/badge/play-station-blue.svg?logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEiIHdpZHRoPSI2MDAiIGhlaWdodD0iNjAwIj48cGF0aCBkPSJNMTI5IDExMWMtNTUgNC05MyA2Ni05MyA3OEwwIDM5OGMtMiA3MCAzNiA5MiA2OSA5MWgxYzc5IDAgODctNTcgMTMwLTEyOGgyMDFjNDMgNzEgNTAgMTI4IDEyOSAxMjhoMWMzMyAxIDcxLTIxIDY5LTkxbC0zNi0yMDljMC0xMi00MC03OC05OC03OGgtMTBjLTYzIDAtOTIgMzUtOTIgNDJIMjM2YzAtNy0yOS00Mi05Mi00MmgtMTV6IiBmaWxsPSIjZmZmIi8+PC9zdmc+
+
+## logoColor parameter
+
+The `logoColor` param can be used to set the color of the logo. Hex, rgb, rgba, hsl, hsla and css named colors can all be used. For SimpleIcons named logos (which are monochrome), the color will be applied to the SimpleIcons logo.
+
+- ![](https://img.shields.io/badge/logo-javascript-blue?logo=javascript) - https://img.shields.io/badge/logo-javascript-blue?logo=javascript
+- ![](https://img.shields.io/badge/logo-javascript-blue?logo=javascript&logoColor=f5f5f5) - https://img.shields.io/badge/logo-javascript-blue?logo=javascript&logoColor=f5f5f5
+
+In the case where Shields hosts a custom multi-colored logo, if the `logoColor` param is passed, the corresponding SimpleIcons logo will be substituted and colored.
+
+- ![](https://img.shields.io/badge/logo-gitlab-blue?logo=gitlab) - https://img.shields.io/badge/logo-gitlab-blue?logo=gitlab
+- ![](https://img.shields.io/badge/logo-gitlab-blue?logo=gitlab&logoColor=white) - https://img.shields.io/badge/logo-gitlab-blue?logo=gitlab&logoColor=white
diff --git a/docs/static-badges.md b/docs/static-badges.md
new file mode 100644
index 0000000..583356f
--- /dev/null
+++ b/docs/static-badges.md
@@ -0,0 +1,13 @@
+# Static Badges
+
+It is possible to use shields.io to make a wide variety of badges displaying static text and/or logos. For example:
+
+- ![any text you like](https://img.shields.io/badge/any%20text-you%20like-blue) - https://img.shields.io/badge/any%20text-you%20like-blue
+- ![just the message](https://img.shields.io/badge/just%20the%20message-8A2BE2) - https://img.shields.io/badge/just%20the%20message-8A2BE2
+- !['for the badge' style](https://img.shields.io/badge/%27for%20the%20badge%27%20style-20B2AA?style=for-the-badge) - https://img.shields.io/badge/%27for%20the%20badge%27%20style-20B2AA?style=for-the-badge
+- ![with a logo](https://img.shields.io/badge/with%20a%20logo-grey?style=for-the-badge&logo=javascript) - https://img.shields.io/badge/with%20a%20logo-grey?style=for-the-badge&logo=javascript
+
+For more info, see:
+
+- [Static badge builder](/badges/static-badge), including full documentation of styles and parameters
+- [Logos](/docs/logos)
diff --git a/docusaurus.config.cjs b/docusaurus.config.cjs
new file mode 100644
index 0000000..b9b76e4
--- /dev/null
+++ b/docusaurus.config.cjs
@@ -0,0 +1,134 @@
+const lightCodeTheme = require('prism-react-renderer').themes.github
+const darkCodeTheme = require('prism-react-renderer').themes.dracula
+const stripCodeBlockLinks = require('./src/plugins/strip-code-block-links')
+
+/** @type {import('@docusaurus/types').Config} */
+const config = {
+ title: 'Shields.io',
+ tagline: 'Concise, consistent, and legible badges',
+ url: 'https://shields.io',
+ baseUrl: '/',
+ onBrokenLinks: 'throw',
+ onBrokenMarkdownLinks: 'warn',
+ favicon: 'img/favicon.ico',
+ organizationName: 'badges',
+ projectName: 'shields',
+
+ themes: [
+ [
+ require.resolve('@easyops-cn/docusaurus-search-local'),
+ /** @type {import("@easyops-cn/docusaurus-search-local").PluginOptions} */
+ ({
+ hashed: true,
+ indexPages: true,
+ }),
+ ],
+ ],
+
+ markdown: {
+ mdx1Compat: {
+ comments: true,
+ admonitions: true,
+ headingIds: true,
+ },
+ },
+
+ presets: [
+ [
+ 'docusaurus-preset-openapi',
+ /** @type {import('docusaurus-preset-openapi').Options} */
+ ({
+ docs: {
+ sidebarPath: require.resolve('./sidebars.cjs'),
+ editUrl: 'https://github.com/badges/shields/tree/master/frontend',
+ },
+ blog: {
+ showReadingTime: true,
+ editUrl: 'https://github.com/badges/shields/tree/master/frontend',
+ },
+ theme: {
+ customCss: require.resolve('./src/css/custom.css'),
+ },
+ api: {
+ path: 'categories',
+ routeBasePath: 'badges',
+ rehypePlugins: [stripCodeBlockLinks],
+ },
+ }),
+ ],
+ ],
+
+ themeConfig:
+ /** @type {import('docusaurus-preset-openapi').ThemeConfig} */
+ ({
+ languageTabs: [],
+ navbar: {
+ title: 'Shields.io',
+ logo: {
+ alt: 'Shields Logo',
+ src: 'img/logo.png',
+ },
+ items: [
+ { to: '/badges', label: 'Badges', position: 'left' },
+ {
+ to: '/docs',
+ label: 'Documentation',
+ position: 'left',
+ },
+ { to: '/community', label: 'Community', position: 'left' },
+ { to: '/blog', label: 'Blog', position: 'left' },
+ {
+ href: 'https://github.com/badges/shields',
+ label: 'GitHub',
+ position: 'right',
+ },
+ ],
+ },
+ footer: {
+ style: 'dark',
+ links: [
+ {
+ title: 'Community',
+ items: [
+ {
+ label: 'GitHub',
+ href: 'https://github.com/badges/shields',
+ },
+ {
+ label: 'Open Collective',
+ href: 'https://opencollective.com/shields',
+ },
+ {
+ label: 'Discord',
+ href: 'https://discord.gg/HjJCwm5',
+ },
+ {
+ label: 'Awesome Badges',
+ href: 'https://github.com/badges/awesome-badges',
+ },
+ ],
+ },
+ {
+ title: 'Stats',
+ items: [
+ {
+ label: 'Service Status',
+ href: 'https://stats.uptimerobot.com/PjXogHB5p',
+ },
+ {
+ label: 'Metrics dashboard',
+ href: 'https://metrics.shields.io/',
+ },
+ ],
+ },
+ ],
+ copyright: `Copyright © ${new Date().getFullYear()} Shields.io. Built with Docusaurus.`,
+ },
+ prism: {
+ theme: lightCodeTheme,
+ darkTheme: darkCodeTheme,
+ },
+ }),
+}
+
+module.exports = config
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..4f2b34c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "badge-frontend",
+ "version": "0.0.0",
+ "description": "Shields.io frontend",
+ "private": true,
+ "homepage": "https://shields.io",
+ "license": "CC0-1.0",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/badges/shields.git",
+ "directory": "frontend"
+ },
+ "scripts": {
+ "test": "echo 'Run tests from parent dir'; false"
+ }
+}
diff --git a/sidebars.cjs b/sidebars.cjs
new file mode 100644
index 0000000..1d0254f
--- /dev/null
+++ b/sidebars.cjs
@@ -0,0 +1,31 @@
+/**
+ * Creating a sidebar enables you to:
+ * - create an ordered group of docs
+ * - render a sidebar for each doc of that group
+ * - provide next/previous navigation
+ *
+ * The sidebars can be generated from the filesystem, or explicitly defined here.
+ *
+ * Create as many sidebars as you want.
+ */
+
+// @ts-check
+
+/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
+const sidebars = {
+ // By default, Docusaurus generates a sidebar from the docs folder structure
+ tutorialSidebar: [{ type: 'autogenerated', dirName: '.' }],
+
+ // But you can create a sidebar manually
+ /*
+ tutorialSidebar: [
+ {
+ type: 'category',
+ label: 'Tutorial',
+ items: ['hello'],
+ },
+ ],
+ */
+}
+
+module.exports = sidebars
diff --git a/src/components/homepage-features.js b/src/components/homepage-features.js
new file mode 100644
index 0000000..a320f1e
--- /dev/null
+++ b/src/components/homepage-features.js
@@ -0,0 +1,108 @@
+import React from 'react'
+import clsx from 'clsx'
+import styles from './homepage-features.module.css'
+
+const FeatureList = [
+ {
+ title: 'Dynamic badges',
+ description: (
+ <>
+
+
+ Show metrics for your project. We've got badges for hundreds of
+ services.
+ >
+ ),
+ },
+ {
+ title: 'Static Badges',
+ description: (
+ <>
+ Create a badge with
+
+
+ >
+ ),
+ },
+ {
+ title: 'Badge-Maker NPM library',
+ description: (
+ <>
+ Render badges in your own application using our{' '}
+
+ NPM library
+
+
+ npm install badge-maker
+ >
+ ),
+ },
+ {
+ title: 'Host your own instance',
+ description: (
+ <>
+ Host a shields instance behind your firewall with our{' '}
+
+ docker image
+
+
+ docker pull shieldsio/shields
+ >
+ ),
+ },
+ {
+ title: 'Love Shields?',
+ description: (
+ <>
+ Please consider{' '}
+
+ donating
+ {' '}
+ to sustain our activities
+ >
+ ),
+ },
+]
+
+function Feature({ title, description }) {
+ return (
+
{description}
++ +
+ +## Backers + +💵 Thank you to all our backers who help keep shields running by donating on OpenCollective. You can support this project by becoming a backer. + ++ +
+ +## Contributors + +🙏 This project exists thanks to all the nice people who contribute their time to work on the project. + ++ +
+ +✨ Shields is helped by these companies which provide a free plan for their product or service: + +{siteConfig.tagline}
+ block.
+ This behaviour is
+ a) mostly unhelpful and
+ b) non-configurable
+
+ This plugin removes tags which appear inside a block.
+ */
+ return tree => {
+ visit(tree, ['mdxJsxTextElement', 'mdxJsxFlowElement', 'element'], node => {
+ if (node.name === 'code' || node.tagName === 'code') {
+ const links = node.children.filter(child => child.tagName === 'a')
+ links.forEach(link => {
+ const linkText = link.children.map(child => child.value).join('')
+ const linkIndex = node.children.indexOf(link)
+ node.children.splice(linkIndex, 1, { type: 'text', value: linkText })
+ })
+ }
+ })
+ }
+}
+
+module.exports = stripCodeBlockLinks
diff --git a/src/theme/ApiDemoPanel/Curl/index.js b/src/theme/ApiDemoPanel/Curl/index.js
new file mode 100644
index 0000000..ee6afd2
--- /dev/null
+++ b/src/theme/ApiDemoPanel/Curl/index.js
@@ -0,0 +1,300 @@
+import React, { useRef, useState, useEffect } from 'react'
+import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
+import clsx from 'clsx'
+import codegen from 'postman-code-generators'
+import { Highlight } from 'prism-react-renderer'
+import { useTypedSelector } from '@theme/ApiDemoPanel/hooks'
+import buildPostmanRequest from '@theme/ApiDemoPanel/buildPostmanRequest'
+import FloatingButton from '@theme/ApiDemoPanel/FloatingButton'
+import styles from 'docusaurus-theme-openapi/lib/theme/ApiDemoPanel/Curl/styles.module.css'
+
+const languageSet = [
+ {
+ tabName: 'cURL',
+ highlight: 'bash',
+ language: 'curl',
+ variant: 'curl',
+ options: {
+ longFormat: false,
+ followRedirect: true,
+ trimRequestBody: true,
+ },
+ },
+ {
+ tabName: 'Node',
+ highlight: 'javascript',
+ language: 'nodejs',
+ variant: 'axios',
+ options: {
+ ES6_enabled: true,
+ followRedirect: true,
+ trimRequestBody: true,
+ },
+ },
+ {
+ tabName: 'Go',
+ highlight: 'go',
+ language: 'go',
+ variant: 'native',
+ options: {
+ followRedirect: true,
+ trimRequestBody: true,
+ },
+ },
+ {
+ tabName: 'Python',
+ highlight: 'python',
+ language: 'python',
+ variant: 'requests',
+ options: {
+ followRedirect: true,
+ trimRequestBody: true,
+ },
+ },
+]
+const languageTheme = {
+ plain: {
+ color: 'var(--ifm-code-color)',
+ },
+ styles: [
+ {
+ types: ['inserted', 'attr-name'],
+ style: {
+ color: 'var(--openapi-code-green)',
+ },
+ },
+ {
+ types: ['string', 'url'],
+ style: {
+ color: 'var(--openapi-code-green)',
+ },
+ },
+ {
+ types: ['builtin', 'char', 'constant', 'function'],
+ style: {
+ color: 'var(--openapi-code-blue)',
+ },
+ },
+ {
+ types: ['punctuation', 'operator'],
+ style: {
+ color: 'var(--openapi-code-dim)',
+ },
+ },
+ {
+ types: ['class-name'],
+ style: {
+ color: 'var(--openapi-code-orange)',
+ },
+ },
+ {
+ types: ['tag', 'arrow', 'keyword'],
+ style: {
+ color: 'var(--openapi-code-purple)',
+ },
+ },
+ {
+ types: ['boolean'],
+ style: {
+ color: 'var(--openapi-code-red)',
+ },
+ },
+ ],
+}
+
+function getBaseUrl() {
+ /*
+ This is a special case for production.
+
+ We want to be able to build the front end with no value set for
+ `BASE_URL` so that staging, prod and self hosting users
+ can all use the same docker image.
+
+ When deployed to staging, we want the frontend on
+ https://staging.shields.io/ to generate badges with the base
+ https://staging.shields.io/
+ (and we want similar behaviour for users hosting their own instance)
+
+ When we promote to production we want https://shields.io/ and
+ https://www.shields.io/ to both generate badges with the base
+ https://img.shields.io/
+
+ For local dev, we can deal with setting the api and front-end
+ being on different ports using the BASE_URL env var
+ */
+ const { protocol, hostname, port } = window.location
+ if (['shields.io', 'www.shields.io'].includes(hostname)) {
+ return 'https://img.shields.io'
+ }
+ if (!port) {
+ return `${protocol}//${hostname}`
+ }
+ return `${protocol}//${hostname}:${port}`
+}
+
+function getServer() {
+ return {
+ url: getBaseUrl(),
+ variables: {},
+ }
+}
+
+function Curl({ postman, codeSamples }) {
+ // TODO: match theme for vscode.
+ const { siteConfig } = useDocusaurusContext()
+ const [copyText, setCopyText] = useState('Copy')
+ const contentType = useTypedSelector(state => state.contentType.value)
+ const accept = useTypedSelector(state => state.accept.value)
+ const server = useTypedSelector(state => state.server.value) || getServer()
+ const body = useTypedSelector(state => state.body)
+ const pathParams = useTypedSelector(state => state.params.path)
+ const queryParams = useTypedSelector(state => state.params.query)
+ const cookieParams = useTypedSelector(state => state.params.cookie)
+ const headerParams = useTypedSelector(state => state.params.header)
+ const auth = useTypedSelector(state => state.auth)
+
+ const langs = [
+ ...(siteConfig?.themeConfig?.languageTabs ?? languageSet),
+ ...codeSamples,
+ ]
+ const [language, setLanguage] = useState(langs[0])
+ const [codeText, setCodeText] = useState('')
+ useEffect(() => {
+ const postmanRequest = buildPostmanRequest(postman, {
+ queryParams,
+ pathParams,
+ cookieParams,
+ contentType,
+ accept,
+ headerParams,
+ body,
+ server,
+ auth,
+ })
+ if (language && !!language.options) {
+ codegen.convert(
+ language.language,
+ language.variant,
+ postmanRequest,
+ language.options,
+ (error, snippet) => {
+ if (error) {
+ return
+ }
+
+ setCodeText(snippet)
+ },
+ )
+ } else if (language && !!language.source) {
+ setCodeText(
+ language.source.replace('$url', postmanRequest.url.toString()),
+ )
+ } else {
+ setCodeText('')
+ }
+ }, [
+ accept,
+ body,
+ contentType,
+ cookieParams,
+ headerParams,
+ language,
+ pathParams,
+ postman,
+ queryParams,
+ server,
+ auth,
+ ])
+ const ref = useRef(null)
+
+ const handleCurlCopy = () => {
+ setCopyText('Copied')
+ setTimeout(() => {
+ setCopyText('Copy')
+ }, 2000)
+
+ if (ref.current?.innerText) {
+ navigator.clipboard.writeText(ref.current.innerText)
+ }
+ }
+
+ if (language === undefined) {
+ return null
+ }
+
+ return (
+ <>
+
+ {langs.map(lang => (
+
+ ))}
+
+
+
+ {({ className, tokens, getLineProps, getTokenProps }) => (
+
+
+
+ {tokens.map((line, i) => (
+ // this does have a key but eslint fails
+ // to detect it because it is an arg to getLineProps()
+ // eslint-disable-next-line react/jsx-key
+
+ {line.map((token, key) => {
+ if (token.types.includes('arrow')) {
+ token.types = ['arrow']
+ }
+
+ return (
+ // this does have a key but eslint fails
+ // to detect it because it is an arg to getLineProps()
+ // eslint-disable-next-line react/jsx-key
+
+ )
+ })}
+ {'\n'}
+
+ ))}
+
+
+
+ )}
+
+ >
+ )
+}
+
+export default Curl
diff --git a/src/theme/ApiDemoPanel/Response/index.js b/src/theme/ApiDemoPanel/Response/index.js
new file mode 100644
index 0000000..898e657
--- /dev/null
+++ b/src/theme/ApiDemoPanel/Response/index.js
@@ -0,0 +1,66 @@
+import React from 'react'
+import { useTypedDispatch, useTypedSelector } from '@theme/ApiDemoPanel/hooks'
+import FloatingButton from '@theme/ApiDemoPanel/FloatingButton'
+import { clearResponse } from 'docusaurus-theme-openapi/lib/theme/ApiDemoPanel/Response/slice'
+
+function formatXml(xml) {
+ const tab = ' '
+ let formatted = ''
+ let indent = ''
+ xml.split(/>\s*).forEach(node => {
+ if (node.match(/^\/\w/)) {
+ // decrease indent by one 'tab'
+ indent = indent.substring(tab.length)
+ }
+
+ formatted += `${indent}<${node}>\r\n`
+
+ if (node.match(/^\w[^>]*[^/]$/)) {
+ // increase indent
+ indent += tab
+ }
+ })
+ return formatted.substring(1, formatted.length - 3)
+}
+
+function Response() {
+ const response = useTypedSelector(state => state.response.value)
+ const dispatch = useTypedDispatch()
+
+ if (response === undefined) {
+ return null
+ }
+
+ let prettyResponse = response
+
+ try {
+ prettyResponse = JSON.stringify(JSON.parse(response), null, 2)
+ } catch {
+ if (response.startsWith(' dispatch(clearResponse())}>
+ {(response.startsWith('
+ )) || (
+
+ {prettyResponse || 'No Response'}
+
+ )}
+
+ )
+}
+
+export default Response
diff --git a/src/theme/DocPaginator/index.js b/src/theme/DocPaginator/index.js
new file mode 100644
index 0000000..7096842
--- /dev/null
+++ b/src/theme/DocPaginator/index.js
@@ -0,0 +1,3 @@
+export default function DocPaginator(props) {
+ return ''
+}
diff --git a/static/.nojekyll b/static/.nojekyll
new file mode 100644
index 0000000..473a0f4
diff --git a/static/img/builder.png b/static/img/builder.png
new file mode 100644
index 0000000..4316ba2
Binary files /dev/null and b/static/img/builder.png differ
diff --git a/static/img/favicon.ico b/static/img/favicon.ico
new file mode 100644
index 0000000..cf73624
Binary files /dev/null and b/static/img/favicon.ico differ
diff --git a/static/img/logo.png b/static/img/logo.png
new file mode 100644
index 0000000..0e33bbd
Binary files /dev/null and b/static/img/logo.png differ