From e5752bdac6d0fbd7809ac33265f472fabd62135c Mon Sep 17 00:00:00 2001 From: omermorad Date: Wed, 7 Oct 2026 22:58:01 +0300 Subject: [PATCH 1/7] ci: build every pull request onBrokenLinks is set to throw, so a broken internal link fails the build. Without CI that failure only surfaced in Netlify after the merge had landed. The Algolia reindex is not run here: it is a no-op outside a production deploy and CI has no crawler credentials. --- .github/workflows/ci.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1d33754 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: CI + +on: + pull_request: + push: + branches: [master] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + + # docusaurus.config.ts sets onBrokenLinks: "throw", so this fails the + # job on any broken internal link. Without it that failure only shows + # up in Netlify after the merge has already landed. + # + # CONTEXT is unset here, so the build omits the analytics tag. The + # Algolia reindex is not run: it is a no-op outside a production + # deploy and CI has no crawler credentials. + - name: Build + run: yarn build From ee2966cafe35a7623b6cf358d0a651aff7de24fd Mon Sep 17 00:00:00 2001 From: omermorad Date: Wed, 7 Oct 2026 22:58:01 +0300 Subject: [PATCH 2/7] fix(analytics): restrict gtag to production deploys The measurement ID was configured unconditionally, so deploy previews and branch deploys reported into the production GA4 property alongside local development. Measured over Apr-Sep, 55% of recorded sessions were not real traffic, and a single developer machine accounted for 50% of all pageviews. Guarding on Netlify's CONTEXT removes the tag from the artifact entirely rather than hiding it at runtime. CONTEXT is unset locally and in CI, so yarn start and yarn build both stop reporting. --- docusaurus.config.ts | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index fc1e736..a70da5e 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -2,6 +2,17 @@ import algoliaConfig from "./config/algolia-config"; import type { Config } from "@docusaurus/types"; import { draculaThemeConfig } from "./config/prisma-theme.config"; +// Netlify sets CONTEXT to "production" | "deploy-preview" | "branch-deploy". +// It is unset locally and in CI, so analytics never fires outside a real +// production deploy. SUITES_FORCE_GTAG is an escape hatch for reproducing a +// tagging bug locally without editing this file. +const isProductionDeploy = + process.env.CONTEXT === "production" || process.env.SUITES_FORCE_GTAG === "1"; + +console.log( + `[docusaurus] CONTEXT=${process.env.CONTEXT ?? "(unset)"} gtag=${isProductionDeploy ? "enabled" : "disabled"}`, +); + const config: Config = { title: "Suites Documentation", tagline: "A unit testing framework for TypeScript backends working with inversion of control and dependency injection", @@ -46,10 +57,14 @@ const config: Config = { customCss: require.resolve("./src/css/custom.css"), }, blog: false, - gtag: { - trackingID: "G-G7FJBNFPJJ", - anonymizeIP: true, - }, + ...(isProductionDeploy + ? { + gtag: { + trackingID: "G-G7FJBNFPJJ", + anonymizeIP: true, + }, + } + : {}), }, ], ], From 3b221f4ae1e53de6317f02800f6e944ade06f5ed Mon Sep 17 00:00:00 2001 From: omermorad Date: Wed, 7 Oct 2026 22:58:01 +0300 Subject: [PATCH 3/7] fix(redirects): consolidate on netlify.toml Two redirect systems were configured for overlapping paths. Netlify skips a non-forced redirect when a real file exists at that path, and the client redirects plugin emitted a real index.html at all 37 of its sources, so the plugin silently won: legacy URLs served 200 with a meta refresh rather than a 301. Meta refresh is a soft signal search engines consolidate slowly, and it covered every high-traffic URL moved by the v4 restructure. All 37 plugin sources were diffed against the 46 netlify.toml rules before deletion. Ten had no identical entry; all ten are covered by existing splats, so no path becomes a 404. Also adds five legacy paths observed 404ing at the edge, and drops four explicit trailing-slash duplicate rules Netlify already matches. --- config/redirects.config.js | 219 ------------------------------------- docusaurus.config.ts | 6 - netlify.toml | 77 +++++++------ package.json | 1 - yarn.lock | 15 --- 5 files changed, 45 insertions(+), 273 deletions(-) delete mode 100644 config/redirects.config.js diff --git a/config/redirects.config.js b/config/redirects.config.js deleted file mode 100644 index d203fd9..0000000 --- a/config/redirects.config.js +++ /dev/null @@ -1,219 +0,0 @@ -/** - * URL Redirects Configuration - * - * Handles redirects for documentation reorganization (v4.0.0 docs restructure) - * Preserves external links from Google, blogs, Stack Overflow, etc. - * - * Based on analytics showing: - * - Quick Start: 2,971 views - * - Installation: 1,580 views - * - API Reference: 1,700 views - * - Solitary Tests: 1,251 views - */ - -module.exports = { - redirects: [ - // ============================================ - // CRITICAL REDIRECTS (High Traffic Pages) - // ============================================ - - // Quick Start (2,971 views) - { - from: '/docs/overview/quickstart', - to: '/docs/get-started/quickstart', - }, - { - from: '/docs/learn/get-started/quickstart', - to: '/docs/get-started/quickstart', - }, - - // Installation (1,580 views) - { - from: '/docs/overview/installation', - to: '/docs/get-started/installation', - }, - { - from: '/docs/learn/get-started/installation', - to: '/docs/get-started/installation', - }, - - // API Reference (1,700 views) - { - from: '/docs/developer-guide/unit-tests/suites-api', - to: '/docs/api-reference/', - }, - { - from: '/docs/learn/unit-tests/suites-api', - to: '/docs/api-reference/', - }, - { - from: '/docs/api-reference/testbed-api', - to: '/docs/api-reference/', - }, - - // Solitary Tests (1,251 views) - { - from: '/docs/developer-guide/unit-tests/solitary', - to: '/docs/guides/solitary', - }, - { - from: '/docs/learn/unit-tests/solitary', - to: '/docs/guides/solitary', - }, - - // Sociable Tests (1,104 views) - { - from: '/docs/developer-guide/unit-tests/sociable', - to: '/docs/guides/sociable', - }, - { - from: '/docs/learn/unit-tests/sociable', - to: '/docs/guides/sociable', - }, - - // ============================================ - // HIGH PRIORITY REDIRECTS - // ============================================ - - // Test Doubles (651 views, 72.7s engagement) - { - from: '/docs/developer-guide/unit-tests/test-doubles', - to: '/docs/guides/test-doubles', - }, - { - from: '/docs/learn/unit-tests/test-doubles', - to: '/docs/guides/test-doubles', - }, - - // Fundamentals (1,389 views) - { - from: '/docs/developer-guide/unit-tests/fundamentals', - to: '/docs/guides/fundamentals', - }, - { - from: '/docs/learn/unit-tests/fundamentals', - to: '/docs/guides/fundamentals', - }, - - // Migrating from Automock (1,082 views) - { - from: '/docs/migrating-from-automock', - to: '/docs/migration-guides/from-automock', - }, - { - from: '/docs/resources/migrating-from-automock', - to: '/docs/migration-guides/from-automock', - }, - { - from: '/docs/overview/migrating-from-automock', - to: '/docs/migration-guides/from-automock', - }, - - // Overview section base (redirect to get-started) - { - from: '/docs/overview', - to: '/docs/get-started/', - }, - - // What is Suites (567 views) - redirect to get-started - { - from: '/docs/overview/what-is-suites', - to: '/docs/get-started/', - }, - - // Problems Solved (933 views) - consolidated into why-suites - { - from: '/docs/overview/problems-solved', - to: '/docs/get-started/why-suites', - }, - { - from: '/docs/resources/problems-solved', - to: '/docs/get-started/why-suites', - }, - - // Comparisons (new page, but redirect just in case) - { - from: '/docs/overview/comparisons', - to: '/docs/get-started/why-suites', - }, - - // Developer Guide Unit Tests - redirect to guides - { - from: '/docs/developer-guide/unit-tests', - to: '/docs/guides/', - }, - - // ============================================ - // ADDITIONAL REDIRECTS (From Netlify 502 logs) - // ============================================ - - // Docs base path - { - from: '/docs', - to: '/docs/get-started/', - }, - - // Introduction section (old structure) - { - from: '/docs/introduction/quick-example', - to: '/docs/get-started/quickstart', - }, - - // Overview motivation - { - from: '/docs/overview/motivation', - to: '/docs/get-started/why-suites', - }, - - // Overview dependency injection (including typo variant) - { - from: '/docs/overview/depdency-injection-and-automock', - to: '/docs/get-started/why-suites', - }, - { - from: '/docs/overview/dependency-injection-and-automock', - to: '/docs/get-started/why-suites', - }, - - // Core concepts section (removed) - { - from: '/docs/core-concepts/dependency-injection', - to: '/docs/get-started/why-suites', - }, - - // API Reference fail-fast (removed) - { - from: '/docs/api-reference/fail-fast', - to: '/docs/api-reference/', - }, - - // Category pages - { - from: '/docs/category/extras', - to: '/docs/guides/', - }, - - // Adapters section (restructured - adapters now bundled) - { - from: '/docs/adapters/inversify', - to: '/docs/get-started/', - }, - { - from: '/docs/adapters/identifiers', - to: '/docs/get-started/', - }, - { - from: '/docs/developer-guide/adapters/inversifyjs', - to: '/docs/get-started/', - }, - { - from: '/docs/developer-guide/adapters/identifiers', - to: '/docs/get-started/', - }, - { - from: '/docs/guides/adapters/inversifyjs', - to: '/docs/get-started/', - }, - - ], -}; diff --git a/docusaurus.config.ts b/docusaurus.config.ts index a70da5e..cfb0a8b 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -68,12 +68,6 @@ const config: Config = { }, ], ], - plugins: [ - [ - "@docusaurus/plugin-client-redirects", - require("./config/redirects.config.js"), - ], - ], themeConfig: { metadata: [ { diff --git a/netlify.toml b/netlify.toml index 2bd9515..9ba0f0b 100644 --- a/netlify.toml +++ b/netlify.toml @@ -41,12 +41,12 @@ status = 301 [[redirects]] from = "/docs/learn/unit-tests/suites-api" -to = "/docs/api-reference/" +to = "/docs/api-reference" status = 301 [[redirects]] from = "/docs/api-reference/testbed-api" -to = "/docs/api-reference/" +to = "/docs/api-reference" status = 301 [[redirects]] @@ -99,17 +99,13 @@ status = 301 [[redirects]] from = "/docs/overview" -to = "/docs/get-started/" +to = "/docs/get-started" status = 301 -[[redirects]] -from = "/docs/overview/" -to = "/docs/get-started/" -status = 301 [[redirects]] from = "/docs/overview/what-is-suites" -to = "/docs/get-started/" +to = "/docs/get-started" status = 301 [[redirects]] @@ -148,7 +144,7 @@ status = 301 [[redirects]] from = "/docs/developer-guide/unit-tests/suites-api*" -to = "/docs/api-reference/" +to = "/docs/api-reference" status = 301 [[redirects]] @@ -173,7 +169,7 @@ status = 301 [[redirects]] from = "/docs/developer-guide/*" -to = "/docs/guides/" +to = "/docs/guides" status = 301 # =========================================== @@ -201,7 +197,7 @@ status = 200 [[redirects]] from = "/docs/category/getting-started*" -to = "/docs/get-started/" +to = "/docs/get-started" status = 301 # =========================================== @@ -210,18 +206,14 @@ status = 301 [[redirects]] from = "/api-reference" -to = "/docs/api-reference/" +to = "/docs/api-reference" status = 301 [[redirects]] from = "/docs" -to = "/docs/get-started/" +to = "/docs/get-started" status = 301 -[[redirects]] -from = "/docs/" -to = "/docs/get-started/" -status = 301 [[redirects]] from = "/docs/introduction/quick-example" @@ -235,40 +227,61 @@ status = 301 [[redirects]] from = "/docs/api-reference/fail-fast" -to = "/docs/api-reference/" +to = "/docs/api-reference" status = 301 [[redirects]] from = "/docs/extras/identical-injections" -to = "/docs/guides/" +to = "/docs/guides" status = 301 -[[redirects]] -from = "/docs/extras/identical-injections/" -to = "/docs/guides/" -status = 301 [[redirects]] from = "/docs/category/extras" -to = "/docs/guides/" +to = "/docs/guides" status = 301 [[redirects]] from = "/docs/category/di-framework-adapters" -to = "/docs/get-started/" +to = "/docs/get-started" status = 301 -[[redirects]] -from = "/docs/category/di-framework-adapters/" -to = "/docs/get-started/" -status = 301 [[redirects]] from = "/docs/adapters/*" -to = "/docs/get-started/" +to = "/docs/get-started" status = 301 [[redirects]] from = "/docs/guides/adapters/inversifyjs" -to = "/docs/get-started/" -status = 301 \ No newline at end of file +to = "/docs/get-started" +status = 301 + +# =========================================== +# LEGACY PATHS OBSERVED 404ing AT THE EDGE +# =========================================== + +[[redirects]] +from = "/docs/getting-started/examples" +to = "/docs/get-started" +status = 301 + +[[redirects]] +from = "/docs/overview/examples" +to = "/docs/get-started" +status = 301 + +[[redirects]] +from = "/docs/category/adapters" +to = "/docs/get-started" +status = 301 + +[[redirects]] +from = "/docs/category/core-concepts" +to = "/docs/guides" +status = 301 + +[[redirects]] +from = "/docs/category/api-reference" +to = "/docs/api-reference" +status = 301 diff --git a/package.json b/package.json index f527ce4..e13f175 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "dependencies": { "@algolia/client-search": "^4.24.0", "@docusaurus/core": "^3.4.0", - "@docusaurus/plugin-client-redirects": "^3.4.0", "@docusaurus/plugin-google-gtag": "^3.4.0", "@docusaurus/plugin-sitemap": "^3.4.0", "@docusaurus/preset-classic": "^3.4.0", diff --git a/yarn.lock b/yarn.lock index fdfaa9c..c25e8bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1349,21 +1349,6 @@ react-helmet-async "*" react-loadable "npm:@docusaurus/react-loadable@6.0.0" -"@docusaurus/plugin-client-redirects@^3.4.0": - version "3.4.0" - resolved "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.4.0.tgz" - integrity sha512-Pr8kyh/+OsmYCvdZhc60jy/FnrY6flD2TEAhl4rJxeVFxnvvRgEhoaIVX8q9MuJmaQoh6frPk94pjs7/6YgBDQ== - dependencies: - "@docusaurus/core" "3.4.0" - "@docusaurus/logger" "3.4.0" - "@docusaurus/utils" "3.4.0" - "@docusaurus/utils-common" "3.4.0" - "@docusaurus/utils-validation" "3.4.0" - eta "^2.2.0" - fs-extra "^11.1.1" - lodash "^4.17.21" - tslib "^2.6.0" - "@docusaurus/plugin-content-blog@3.4.0": version "3.4.0" resolved "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.4.0.tgz" From 7cf9797a0237ca5125459a2609b4acc7ff89c341 Mon Sep 17 00:00:00 2001 From: omermorad Date: Wed, 7 Oct 2026 22:58:01 +0300 Subject: [PATCH 4/7] fix(seo): make the trailing-slash URL form canonical Every leaf doc page contradicted itself. The canonical tag and sitemap used the slashless form while Netlify Pretty URLs 301s that form to the slash form, so each canonical URL redirected away from itself. Google crawled a sitemap URL, was redirected, and landed on a page pointing back at the URL it had just left. The four category indexes were already consistent; the 16 leaves were not. trailingSlash: true adopts the form Netlify already serves, so no live URL changes and no redirect reverses direction. Pretty URLs is pinned in netlify.toml rather than left to the dashboard, since file configuration overrides UI configuration and the two settings must agree. Relative sibling links are rewritten to absolute paths: with a trailing slash on the page URL, ./solitary resolved as a child of the current page rather than a sibling. The build's broken-link check caught this. Also excludes /404 and /search from the sitemap, and points the header's documentation links at their destination instead of through a redirect. --- docs/guides/sociable.md | 4 +- docs/guides/solitary.md | 2 +- docs/guides/test-doubles.md | 4 +- docusaurus.config.ts | 7 +++ netlify.toml | 96 ++++++++++++++++++--------------- src/components/Header/index.tsx | 4 +- static/llms.txt | 32 +++++------ 7 files changed, 82 insertions(+), 67 deletions(-) diff --git a/docs/guides/sociable.md b/docs/guides/sociable.md index ed7705c..29af047 100644 --- a/docs/guides/sociable.md +++ b/docs/guides/sociable.md @@ -11,7 +11,7 @@ import TabItem from '@theme/TabItem'; > **What this covers:** Testing real component (class) interactions while controlling external dependencies \ > **Time to read:** ~15 minutes \ -> **Prerequisites:** [Unit Testing Fundamentals](/docs/guides/fundamentals), [Solitary Unit Tests](./solitary), [Test Doubles](./test-doubles) \ +> **Prerequisites:** [Unit Testing Fundamentals](/docs/guides/fundamentals), [Solitary Unit Tests](/docs/guides/solitary/), [Test Doubles](/docs/guides/test-doubles/) \ > **Best for:** Verifying components (classes) work together correctly, catching integration bugs while maintaining test speed Sociable unit tests verify how components interact with their real dependencies while keeping external I/O operations under control. This approach identifies bugs in how business logic components work together - bugs that solitary tests miss. @@ -325,5 +325,5 @@ Sociable tests work alongside solitary tests to provide comprehensive coverage: After understanding sociable testing, explore these resources: -- **[Test Doubles](./test-doubles)**: Core concepts of mocking and stubbing +- **[Test Doubles](/docs/guides/test-doubles/)**: Core concepts of mocking and stubbing - **[Suites Examples Repository](https://github.com/suites-dev/examples)**: Working examples of sociable testing patterns diff --git a/docs/guides/solitary.md b/docs/guides/solitary.md index 7a7427c..91e3c4c 100644 --- a/docs/guides/solitary.md +++ b/docs/guides/solitary.md @@ -8,7 +8,7 @@ description: Testing in isolation with Suites > **What this covers:** Writing unit tests that isolate a single component (class) using automatic mocking \ > **Time to read:** ~8 minutes \ -> **Prerequisites:** [Unit Testing Fundamentals](/docs/guides/fundamentals), [Test Doubles](./test-doubles) \ +> **Prerequisites:** [Unit Testing Fundamentals](/docs/guides/fundamentals), [Test Doubles](/docs/guides/test-doubles/) \ > **Best for:** Testing component logic in complete isolation, controlling all inputs for predictable results Solitary unit tests evaluate a single unit of work in complete isolation from its external dependencies. These tests use diff --git a/docs/guides/test-doubles.md b/docs/guides/test-doubles.md index 9ead5e1..bef0b08 100644 --- a/docs/guides/test-doubles.md +++ b/docs/guides/test-doubles.md @@ -211,8 +211,8 @@ See [Sociable Unit Tests](/docs/guides/sociable) for more information. Learn more about using test doubles in practice: -- **[Solitary Unit Tests](./solitary)**: Test components in complete isolation using automatic mocking -- **[Sociable Unit Tests](./sociable)**: Test multiple components together with real implementations +- **[Solitary Unit Tests](/docs/guides/solitary/)**: Test components in complete isolation using automatic mocking +- **[Sociable Unit Tests](/docs/guides/sociable/)**: Test multiple components together with real implementations ## Additional Resources diff --git a/docusaurus.config.ts b/docusaurus.config.ts index cfb0a8b..869d4d4 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -19,6 +19,7 @@ const config: Config = { organizationName: "suites-dev", url: "https://suites.dev", baseUrl: "/", + trailingSlash: true, onBrokenLinks: "throw", onBrokenMarkdownLinks: "throw", favicon: "img/favicon.png", @@ -65,6 +66,12 @@ const config: Config = { }, } : {}), + sitemap: { + changefreq: "weekly", + priority: 0.5, + filename: "sitemap.xml", + ignorePatterns: ["/404", "/404/", "/search", "/search/"], + }, }, ], ], diff --git a/netlify.toml b/netlify.toml index 9ba0f0b..681f152 100644 --- a/netlify.toml +++ b/netlify.toml @@ -15,58 +15,66 @@ command = "yarn run build && yarn algolia:reindex" publish = "build" +# Pinned rather than left to the dashboard toggle, because file configuration +# overrides UI configuration. Pretty URLs serves the slash-terminated form, +# which is what `trailingSlash: true` in docusaurus.config.ts declares as +# canonical. The two settings must agree or every page redirects away from +# its own canonical URL. +[build.processing.html] +pretty_urls = true + # =========================================== # CRITICAL REDIRECTS (High Traffic Pages) # =========================================== [[redirects]] from = "/docs/overview/quickstart" -to = "/docs/get-started/quickstart" +to = "/docs/get-started/quickstart/" status = 301 [[redirects]] from = "/docs/learn/get-started/quickstart" -to = "/docs/get-started/quickstart" +to = "/docs/get-started/quickstart/" status = 301 [[redirects]] from = "/docs/overview/installation" -to = "/docs/get-started/installation" +to = "/docs/get-started/installation/" status = 301 [[redirects]] from = "/docs/learn/get-started/installation" -to = "/docs/get-started/installation" +to = "/docs/get-started/installation/" status = 301 [[redirects]] from = "/docs/learn/unit-tests/suites-api" -to = "/docs/api-reference" +to = "/docs/api-reference/" status = 301 [[redirects]] from = "/docs/api-reference/testbed-api" -to = "/docs/api-reference" +to = "/docs/api-reference/" status = 301 [[redirects]] from = "/docs/learn/unit-tests/solitary" -to = "/docs/guides/solitary" +to = "/docs/guides/solitary/" status = 301 [[redirects]] from = "/docs/learn/unit-tests/sociable" -to = "/docs/guides/sociable" +to = "/docs/guides/sociable/" status = 301 [[redirects]] from = "/docs/learn/unit-tests/test-doubles" -to = "/docs/guides/test-doubles" +to = "/docs/guides/test-doubles/" status = 301 [[redirects]] from = "/docs/learn/unit-tests/fundamentals" -to = "/docs/guides/fundamentals" +to = "/docs/guides/fundamentals/" status = 301 # =========================================== @@ -75,22 +83,22 @@ status = 301 [[redirects]] from = "/docs/migrating-from-automock" -to = "/docs/migration-guides/from-automock" +to = "/docs/migration-guides/from-automock/" status = 301 [[redirects]] from = "/docs/resources/migrating-from-automock" -to = "/docs/migration-guides/from-automock" +to = "/docs/migration-guides/from-automock/" status = 301 [[redirects]] from = "/docs/overview/migrating-from-automock" -to = "/docs/migration-guides/from-automock" +to = "/docs/migration-guides/from-automock/" status = 301 [[redirects]] from = "/docs/getting-started/change-log" -to = "/docs/migration-guides/from-automock" +to = "/docs/migration-guides/from-automock/" status = 301 # =========================================== @@ -99,43 +107,43 @@ status = 301 [[redirects]] from = "/docs/overview" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 [[redirects]] from = "/docs/overview/what-is-suites" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 [[redirects]] from = "/docs/overview/problems-solved" -to = "/docs/get-started/why-suites" +to = "/docs/get-started/why-suites/" status = 301 [[redirects]] from = "/docs/resources/problems-solved" -to = "/docs/get-started/why-suites" +to = "/docs/get-started/why-suites/" status = 301 [[redirects]] from = "/docs/overview/comparisons" -to = "/docs/get-started/why-suites" +to = "/docs/get-started/why-suites/" status = 301 [[redirects]] from = "/docs/overview/motivation" -to = "/docs/get-started/why-suites" +to = "/docs/get-started/why-suites/" status = 301 [[redirects]] from = "/docs/overview/depdency-injection-and-automock" -to = "/docs/get-started/why-suites" +to = "/docs/get-started/why-suites/" status = 301 [[redirects]] from = "/docs/overview/dependency-injection-and-automock" -to = "/docs/get-started/why-suites" +to = "/docs/get-started/why-suites/" status = 301 # =========================================== @@ -144,32 +152,32 @@ status = 301 [[redirects]] from = "/docs/developer-guide/unit-tests/suites-api*" -to = "/docs/api-reference" +to = "/docs/api-reference/" status = 301 [[redirects]] from = "/docs/developer-guide/unit-tests/solitary*" -to = "/docs/guides/solitary" +to = "/docs/guides/solitary/" status = 301 [[redirects]] from = "/docs/developer-guide/unit-tests/sociable*" -to = "/docs/guides/sociable" +to = "/docs/guides/sociable/" status = 301 [[redirects]] from = "/docs/developer-guide/unit-tests/test-doubles*" -to = "/docs/guides/test-doubles" +to = "/docs/guides/test-doubles/" status = 301 [[redirects]] from = "/docs/developer-guide/unit-tests/fundamentals*" -to = "/docs/guides/fundamentals" +to = "/docs/guides/fundamentals/" status = 301 [[redirects]] from = "/docs/developer-guide/*" -to = "/docs/guides" +to = "/docs/guides/" status = 301 # =========================================== @@ -197,7 +205,7 @@ status = 200 [[redirects]] from = "/docs/category/getting-started*" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 # =========================================== @@ -206,55 +214,55 @@ status = 301 [[redirects]] from = "/api-reference" -to = "/docs/api-reference" +to = "/docs/api-reference/" status = 301 [[redirects]] from = "/docs" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 [[redirects]] from = "/docs/introduction/quick-example" -to = "/docs/get-started/quickstart" +to = "/docs/get-started/quickstart/" status = 301 [[redirects]] from = "/docs/core-concepts/dependency-injection" -to = "/docs/get-started/why-suites" +to = "/docs/get-started/why-suites/" status = 301 [[redirects]] from = "/docs/api-reference/fail-fast" -to = "/docs/api-reference" +to = "/docs/api-reference/" status = 301 [[redirects]] from = "/docs/extras/identical-injections" -to = "/docs/guides" +to = "/docs/guides/" status = 301 [[redirects]] from = "/docs/category/extras" -to = "/docs/guides" +to = "/docs/guides/" status = 301 [[redirects]] from = "/docs/category/di-framework-adapters" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 [[redirects]] from = "/docs/adapters/*" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 [[redirects]] from = "/docs/guides/adapters/inversifyjs" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 # =========================================== @@ -263,25 +271,25 @@ status = 301 [[redirects]] from = "/docs/getting-started/examples" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 [[redirects]] from = "/docs/overview/examples" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 [[redirects]] from = "/docs/category/adapters" -to = "/docs/get-started" +to = "/docs/get-started/" status = 301 [[redirects]] from = "/docs/category/core-concepts" -to = "/docs/guides" +to = "/docs/guides/" status = 301 [[redirects]] from = "/docs/category/api-reference" -to = "/docs/api-reference" +to = "/docs/api-reference/" status = 301 diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 5008a8e..6497274 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -55,7 +55,7 @@ export default function Header(): JSX.Element {