diff --git a/docs/README.md b/docs/README.md
index 1da3925a49e..3fabcfdc979 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,3 +1,5 @@
+import DocsifyForwarder from '@site/src/components/DocsifyForwarder';
+
# Quantum Mechanical Keyboard Firmware
## What is QMK Firmware?
@@ -43,3 +45,5 @@ There are a lot of ways you can contribute to the QMK Community. The easiest way
* [Translate our documentation into your language](translating.md)
* [Report a bug](https://github.com/qmk/qmk_firmware/issues/new/choose)
* [Open a Pull Request](contributing.md)
+
+
\ No newline at end of file
diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js
index 553e0a87468..257ed734e55 100644
--- a/docs/docusaurus.config.js
+++ b/docs/docusaurus.config.js
@@ -1,169 +1,290 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion
-const lightCodeTheme = require('prism-react-renderer/themes/github');
-const darkCodeTheme = require('prism-react-renderer/themes/dracula');
+const lightCodeTheme = require("prism-react-renderer/themes/github");
+const darkCodeTheme = require("prism-react-renderer/themes/dracula");
/** @type {import('@docusaurus/types').Config} */
const config = {
- title: 'QMK Firmware',
- tagline: 'Potatoes are cool',
- favicon: 'img/favicon.ico',
+ title: "QMK Firmware",
+ tagline: "The full documentation of the open-source firmware",
+ favicon: "img/favicon.ico",
- // Set the production url of your site here
- url: 'https://docs.qmk.fm',
- // Set the // pathname under which your site is served
- // For GitHub pages deployment, it is often '//'
- baseUrl: '/',
+ // Set the production url of your site here
+ url: "https://docs.qmk.fm",
+ // Set the // pathname under which your site is served
+ // For GitHub pages deployment, it is often '//'
+ baseUrl: "/",
- // GitHub pages deployment config.
- // If you aren't using GitHub pages, you don't need these.
- organizationName: 'qmk', // Usually your GitHub org/user name.
- projectName: 'qmk_firmware', // Usually your repo name.
+ // GitHub pages deployment config.
+ // If you aren't using GitHub pages, you don't need these.
+ organizationName: "qmk", // Usually your GitHub org/user name.
+ projectName: "qmk_firmware", // Usually your repo name.
- onBrokenLinks: 'throw',
- onBrokenMarkdownLinks: 'warn',
+ onBrokenLinks: "throw",
+ onBrokenMarkdownLinks: "warn",
- // Even if you don't use internalization, you can use this field to set useful
- // metadata like html lang. For example, if your site is Chinese, you may want
- // to replace "en" with "zh-Hans".
- i18n: {
- defaultLocale: 'en',
- locales: ['en'],//, 'ja', 'zh-cn'],
- },
+ // Even if you don't use internalization, you can use this field to set useful
+ // metadata like html lang. For example, if your site is Chinese, you may want
+ // to replace "en" with "zh-Hans".
+ i18n: {
+ defaultLocale: "en",
+ locales: ["en"], //, 'ja', 'zh-cn'],
+ },
- presets: [
- [
- 'classic',
- /** @type {import('@docusaurus/preset-classic').Options} */
- ({
- docs: {
- sidebarPath: require.resolve('./sidebars.js'),
- path: ".",
- routeBasePath: "/",
- exclude: [
- "node_modules",
- "src",
- "static",
- "ja",
- "zh-cn",
- "gitbook",
- // "ChangeLog"
- ],
- editUrl:
- 'https://github.com/qmk/qmk_firmware/edit/master/docs/',
- },
- blog: false,
- theme: {
- customCss: require.resolve('./src/css/custom.css'),
- },
- }),
+ presets: [
+ [
+ "classic",
+ /** @type {import('@docusaurus/preset-classic').Options} */
+ ({
+ docs: {
+ sidebarPath: require.resolve("./sidebars.js"),
+ path: ".",
+ routeBasePath: "/",
+ exclude: [
+ "node_modules",
+ "src",
+ "static",
+ "ja",
+ "zh-cn",
+ "gitbook",
+ // "ChangeLog"
+ ],
+ editUrl:
+ "https://github.com/qmk/qmk_firmware/edit/master/docs/",
+ },
+ blog: false,
+ theme: {
+ customCss: require.resolve("./src/css/custom.css"),
+ },
+ }),
+ ],
],
- ],
- themeConfig:
- /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
- ({
- image: 'img/qmk-social-card.jpg',
- navbar: {
- title: 'QMK Firmware Docs',
- logo: {
- alt: 'QMK Firmware',
- src: 'img/qmk-new-light.svg',
- srcDark: 'img/qmk-new-dark.svg',
- width: 32,
- height: 32,
- },
- items: [
- {
- type: 'localeDropdown',
- position: 'right',
- },
- {
- href: 'https://github.com/qmk/qmk_firmware',
- label: 'GitHub',
- position: 'right',
- },
+ plugins: [
+ [
+ "@docusaurus/plugin-client-redirects",
+ {
+ fromExtensions: ['md', 'html'],
+ redirects: [
+ // from index.html
+ {
+ from: '/adding_a_keyboard_to_qmk',
+ to: '/hardware_keyboard_guidelines',
+ },
+ {
+ from: '/build_environment_setup',
+ to: '/newbs_getting_started',
+ },
+ {
+ from: '/cli_dev_configuration',
+ to: '/cli_configuration',
+ },
+ {
+ from: '/dynamic_macros',
+ to: '/feature_dynamic_macros',
+ },
+ {
+ from: '/feature_common_shortcuts',
+ to: '/feature_advanced_keycodes',
+ },
+ {
+ from: '/glossary',
+ to: '/reference_glossary',
+ },
+ {
+ from: '/key_lock',
+ to: '/feature_key_lock',
+ },
+ {
+ from: '/make_instructions',
+ to: '/getting_started_make_guide',
+ },
+ {
+ from: '/space_cadet_shift',
+ to: '/feature_space_cadet_shift',
+ },
+ {
+ from: '/getting_started_getting_help',
+ to: '/support',
+ },
+ {
+ from: '/tap_dance',
+ to: '/feature_tap_dance',
+ },
+ {
+ from: '/unicode',
+ to: '/feature_unicode',
+ },
+ {
+ from: '/python_development',
+ to: '/cli_development',
+ },
+ {
+ from: '/getting_started_build_tools',
+ to: '/newbs_getting_started',
+ },
+ {
+ from: '/tutorial',
+ to: '/newbs',
+ },
+ // from redirects.json
+ // {
+ // from: "/adding_a_keyboard_to_qmk",
+ // to: "/hardware_keyboard_guidelines"
+ // },
+ // {
+ // from: "/build_environment_setup",
+ // to: "/getting_started_build_tools"
+ // },
+ // {
+ // from: "/dynamic_macros",
+ // to: "/feature_dynamic_macros"
+ // },
+ // {
+ // from: "/feature_common_shortcuts",
+ // to: "/feature_advanced_keycodes"
+ // },
+ // {
+ // from: "/glossary",
+ // to: "/reference_glossary"
+ // },
+ // {
+ // from: "/key_lock",
+ // to: "/feature_key_lock"
+ // },
+ // {
+ // from: "/make_instructions",
+ // to: "/getting_started_make_guide"
+ // },
+ // {
+ // from: "/porting_your_keyboard_to_qmk",
+ // to: "/hardware_avr"
+ // },
+ // {
+ // from: "/space_cadet_shift",
+ // to: "/feature_space_cadet_shift"
+ // },
+ // {
+ // from: "/tap_dance",
+ // to: "/feature_tap_dance"
+ // },
+ // {
+ // from: "/unicode",
+ // to: "/feature_unicode"
+ // },
+ // {
+ // from: "/python_development",
+ // to: "/cli_development"
+ // }
+ ],
+ },
],
- },
- docs: {
- sidebar: {
- autoCollapseCategories: false
- }
- },
- footer: {
- style: 'dark',
- links: [
- {
- title: 'Docs',
- items: [
- {
- label: 'Docs',
- to: '/',
- },
- ],
- },
- {
- title: 'Community',
- items: [
- {
- label: 'Discord',
- href: 'https://discord.gg/Uq7gcHh',
- },
- {
- label: 'Reddit',
- href: 'https://reddit.com/r/olkb',
- },
- ],
- },
- {
- title: 'More',
- items: [
- {
- label: 'GitHub',
- href: 'https://github.com/qmk/qmk_firmware',
- },
- ],
- },
- ],
- copyright: `Copyright © ${new Date().getFullYear()} QMK. Built with Docusaurus.`,
- },
- prism: {
- theme: lightCodeTheme,
- darkTheme: darkCodeTheme,
- },
- // applied for - will fill out once we hear back
- //
- // algolia: {
- // // The application ID provided by Algolia
- // appId: 'YOUR_APP_ID',
+ ],
- // // Public API key: it is safe to commit it
- // apiKey: 'YOUR_SEARCH_API_KEY',
+ themeConfig:
+ /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+ ({
+ image: "img/qmk-social-card.jpg",
+ navbar: {
+ title: "QMK Firmware Docs",
+ logo: {
+ alt: "QMK Firmware",
+ src: "img/qmk-new-light.svg",
+ srcDark: "img/qmk-new-dark.svg",
+ width: 32,
+ height: 32,
+ },
+ items: [
+ // {
+ // type: 'localeDropdown',
+ // position: 'right',
+ // },
+ {
+ href: "https://github.com/qmk/qmk_firmware",
+ label: "GitHub",
+ position: "right",
+ },
+ ],
+ },
+ docs: {
+ sidebar: {
+ autoCollapseCategories: false,
+ },
+ },
+ footer: {
+ style: "dark",
+ links: [
+ {
+ title: "Docs",
+ items: [
+ {
+ label: "Docs",
+ to: "/",
+ },
+ ],
+ },
+ {
+ title: "Community",
+ items: [
+ {
+ label: "Discord",
+ href: "https://discord.gg/Uq7gcHh",
+ },
+ {
+ label: "Reddit",
+ href: "https://reddit.com/r/olkb",
+ },
+ ],
+ },
+ {
+ title: "More",
+ items: [
+ {
+ label: "GitHub",
+ href: "https://github.com/qmk/qmk_firmware",
+ },
+ ],
+ },
+ ],
+ copyright: `Copyright © ${new Date().getFullYear()} QMK. Built with Docusaurus.`,
+ },
+ prism: {
+ theme: lightCodeTheme,
+ darkTheme: darkCodeTheme,
+ },
+ // applied for - will fill out once we hear back
+ //
+ // algolia: {
+ // // The application ID provided by Algolia
+ // appId: 'YOUR_APP_ID',
- // indexName: 'YOUR_INDEX_NAME',
+ // // Public API key: it is safe to commit it
+ // apiKey: 'YOUR_SEARCH_API_KEY',
- // // Optional: see doc section below
- // contextualSearch: true,
+ // indexName: 'YOUR_INDEX_NAME',
- // // Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them.
- // externalUrlRegex: 'external\\.com|domain\\.com',
+ // // Optional: see doc section below
+ // contextualSearch: true,
- // // Optional: Replace parts of the item URLs from Algolia. Useful when using the same search index for multiple deployments using a different baseUrl. You can use regexp or string in the `from` param. For example: localhost:3000 vs myCompany.com/docs
- // replaceSearchResultPathname: {
- // from: '/docs/', // or as RegExp: /\/docs\//
- // to: '/',
- // },
+ // // Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them.
+ // externalUrlRegex: 'external\\.com|domain\\.com',
- // // Optional: Algolia search parameters
- // searchParameters: {},
+ // // Optional: Replace parts of the item URLs from Algolia. Useful when using the same search index for multiple deployments using a different baseUrl. You can use regexp or string in the `from` param. For example: localhost:3000 vs myCompany.com/docs
+ // replaceSearchResultPathname: {
+ // from: '/docs/', // or as RegExp: /\/docs\//
+ // to: '/',
+ // },
- // // Optional: path for search page that enabled by default (`false` to disable it)
- // searchPagePath: 'search',
+ // // Optional: Algolia search parameters
+ // searchParameters: {},
- // //... other Algolia params
- // },
- }),
+ // // Optional: path for search page that enabled by default (`false` to disable it)
+ // searchPagePath: 'search',
+
+ // //... other Algolia params
+ // },
+ }),
};
module.exports = config;
diff --git a/docs/package-lock.json b/docs/package-lock.json
index a0877ec70db..34afd43ed86 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@docusaurus/core": "2.4.0",
+ "@docusaurus/plugin-client-redirects": "^2.4.0",
"@docusaurus/preset-classic": "2.4.0",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.2.1",
@@ -2185,6 +2186,29 @@
"react-dom": "*"
}
},
+ "node_modules/@docusaurus/plugin-client-redirects": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-2.4.0.tgz",
+ "integrity": "sha512-HsS+Dc2ZLWhfpjYJ5LIrOB/XfXZcElcC7o1iA4yIVtiFz+LHhwP863fhqbwSJ1c6tNDOYBH3HwbskHrc/PIn7Q==",
+ "dependencies": {
+ "@docusaurus/core": "2.4.0",
+ "@docusaurus/logger": "2.4.0",
+ "@docusaurus/utils": "2.4.0",
+ "@docusaurus/utils-common": "2.4.0",
+ "@docusaurus/utils-validation": "2.4.0",
+ "eta": "^2.0.0",
+ "fs-extra": "^10.1.0",
+ "lodash": "^4.17.21",
+ "tslib": "^2.4.0"
+ },
+ "engines": {
+ "node": ">=16.14"
+ },
+ "peerDependencies": {
+ "react": "^16.8.4 || ^17.0.0",
+ "react-dom": "^16.8.4 || ^17.0.0"
+ }
+ },
"node_modules/@docusaurus/plugin-content-blog": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.0.tgz",
diff --git a/docs/package.json b/docs/package.json
index a5d7d1ff9b9..f86831455f0 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -15,6 +15,7 @@
},
"dependencies": {
"@docusaurus/core": "2.4.0",
+ "@docusaurus/plugin-client-redirects": "^2.4.0",
"@docusaurus/preset-classic": "2.4.0",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.2.1",
diff --git a/docs/src/components/DocsifyForwarder.js b/docs/src/components/DocsifyForwarder.js
new file mode 100644
index 00000000000..9fae481da09
--- /dev/null
+++ b/docs/src/components/DocsifyForwarder.js
@@ -0,0 +1,18 @@
+import React, { useEffect } from 'react';
+import { useHistory } from 'react-router-dom';
+
+function removeHashSlash(url) {
+ return url.replace(/\/#\//, '/');
+}
+
+export default function DocsifyForwarder(props) {
+ const history = useHistory();
+ const currentUrl = window.location.href;
+ if (currentUrl.includes('/#/')) {
+ const newUrl = removeHashSlash(currentUrl);
+ window.history.replaceState({}, '', newUrl);
+ const relativePath = new URL(newUrl).pathname;
+ history.push(relativePath);
+ }
+ return "";
+}
\ No newline at end of file