Repository: graphql-markdown/graphql-markdown
Pull request #1164 (2023-12-18 19:57:34)

✨ Generic doc option for markdown front matter
# Description

Add a generic option `frontMatter` to `docOptions` accepting a k/v map that will be printed for every Markdown page generated.

This supports requests like #1150.

```js
frontMatter: { 
  draft: true, 
  hide_table_of_contents: true,
}
```

```yaml
---
id: an-object-type-name
title: An Object Type Name
draft: true
hide_table_of_contents: true
---
```

This will deprecate the options `docOptions.toc`  and `docOptions.pagination`.

# Checklist

- [x] My changes follow the [contributing guidelines](https://github.com/graphql-markdown/graphql-markdown/blob/main/CONTRIBUTING.md) of this project.
- [x] I have performed a self-review of my code.
- [x] I have made corresponding changes to the documentation.
- [x] I have added tests that prove my fix is effective or that my changes work.
- [x] New and existing unit tests pass locally with my changes.


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164) **Quality Gate passed**  
Kudos, no new issues were introduced!

[0 New issues](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
[0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
No data about Coverage  
[1.3% Duplication on New Code](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=1164&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164)


codesee-maps[bot]: <details open>
<summary><b>👇 <a href="https://app.codesee.io/r/reviews?pr=1164&src=https%3A%2F%2Fgithub.com%2Fgraphql-markdown%2Fgraphql-markdown">Click on the image</a> for a new way to code review</b>
</summary>

####

[![Review these changes using an interactive CodeSee Map](https://s3.us-east-2.amazonaws.com/maps.codesee.io/images/github/graphql-markdown/graphql-markdown/1164/022a4b19/03d5ef5a50f78d235791abcdef51e2fc581cc161.svg)](https://app.codesee.io/r/reviews?pr=1164&src=https%3A%2F%2Fgithub.com%2Fgraphql-markdown%2Fgraphql-markdown)

#### Legend
<img src="https://app.codesee.io/Legend_v3.png" alt="CodeSee Map legend" width="220" height="156">
</details>
sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164) **Quality Gate passed**  
Kudos, no new issues were introduced!

[0 New issues](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
[0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
No data about Coverage  
[1.3% Duplication on New Code](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=1164&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164)


coveralls: 
[![Coverage Status](https://coveralls.io/builds/64640315/badge)](https://coveralls.io/builds/64640315)

coverage: 94.148% (+0.2%) from 93.997%
when pulling **bdc734a2a51b8e06e62faf2b2ac89fc606b134d0 on feat/markdown-front-matter**
into **9c5643474921e582c838ba395b4023fed0e13b3b on main**.

sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164) **Quality Gate passed**  
Kudos, no new issues were introduced!

[0 New issues](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
[0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
No data about Coverage  
[0.9% Duplication on New Code](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=1164&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164) **Quality Gate passed**  
Kudos, no new issues were introduced!

[0 New issues](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
[0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
No data about Coverage  
[0.9% Duplication on New Code](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=1164&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164) **Quality Gate passed**  
Kudos, no new issues were introduced!

[0 New issues](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
[0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=1164&resolved=false&inNewCodePeriod=true)  
No data about Coverage  
[0.9% Duplication on New Code](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=1164&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=1164)



Patch:
diff --git a/.knip.json b/.knip.json
index ab3e4397..3b1af877 100644
--- a/.knip.json
+++ b/.knip.json
@@ -15,7 +15,11 @@
       "entry": ["src/index.ts!"],
       "project": ["**/*.ts!"],
       "ignore": ["**/__mocks__/**/*.ts"],
-      "ignoreDependencies": ["@graphql-markdown/diff", "@graphql-markdown/printer-legacy", "graphql-config"]
+      "ignoreDependencies": [
+        "@graphql-markdown/diff",
+        "@graphql-markdown/printer-legacy",
+        "graphql-config"
+      ]
     },
     "packages/utils": {
       "entry": ["src/index.ts!"],
diff --git a/Earthfile b/Earthfile
index 36da14b4..89541038 100644
--- a/Earthfile
+++ b/Earthfile
@@ -102,7 +102,7 @@ build-examples:
   WORKDIR /docusaurus2
   RUN npm install prettier
   RUN mkdir $TARGET
-  DO +GQLMD --options="--homepage data/anilist.md --schema https://graphql.anilist.co/ --base . --link /${TARGET}/default --force --pretty --noPagination --deprecated group"
+  DO +GQLMD --options="--homepage data/anilist.md --schema https://graphql.anilist.co/ --base . --link /${TARGET}/default --force --pretty --deprecated group"
   RUN mv docs ./$TARGET/default
   DO +GQLMD --id="schema_with_grouping" --options="--homepage data/groups.md --schema data/schema_with_grouping.graphql --groupByDirective @doc(category|=Common) --base . --link /${TARGET}/group-by --skip @noDoc --index --noParentType --noRelatedType --deprecated group"
   RUN mv docs ./$TARGET/group-by
diff --git a/docs/advanced/custom-directive.md b/docs/advanced/custom-directive.md
index 051b9166..790ec015 100644
--- a/docs/advanced/custom-directive.md
+++ b/docs/advanced/custom-directive.md
@@ -135,7 +135,6 @@ The packages `@graphql-markdown/helpers` and `@graphql-markdown/graphql` provide
 npm i @graphql-markdown/helpers
 ```
 
-
 :::
 
 ### `@graphql-markdown/helpers`
diff --git a/docs/advanced/homepage.md b/docs/advanced/homepage.md
index b47f78c4..1a9008c6 100644
--- a/docs/advanced/homepage.md
+++ b/docs/advanced/homepage.md
@@ -32,5 +32,4 @@ sidebar_class_name: navbar__toggle
 ---
 ```
 
-
 :::
diff --git a/docs/advanced/schema-loading.md b/docs/advanced/schema-loading.md
index e7ba5487..3ba8e552 100644
--- a/docs/advanced/schema-loading.md
+++ b/docs/advanced/schema-loading.md
@@ -72,7 +72,7 @@ plugins: [
         UrlLoader: {
           module: "@graphql-tools/url-loader",
           options: {
-            headers: { 
+            headers: {
               "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
              }
           }
diff --git a/docs/configuration.md b/docs/configuration.md
index b51bbb86..596fa822 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -119,9 +119,6 @@ extensions:
           method: "POST"
     printTypeOptions:
       deprecated: "group"
-    docOptions:
-      pagination: false,
-      toc: false
 ```
 
 :::warning
@@ -139,7 +136,7 @@ Note that **`schema` is not part of the extension configuration**, but part of t
 
 GraphQL-Markdown allows mixing the different configuration, and build the final configuration as follow:
 
-  1. Default configuration
-  2. `.graphqlrc` configuration file
-  3. Docusaurus plugin configuration
-  4. CLI flags
+1. Default configuration
+2. `.graphqlrc` configuration file
+3. Docusaurus plugin configuration
+4. CLI flags
diff --git a/docs/settings.md b/docs/settings.md
index e35fc618..b7295cab 100644
--- a/docs/settings.md
+++ b/docs/settings.md
@@ -48,22 +48,23 @@ If the package is missing, then the change detection is always skipped.
 npm install @graphql-markdown/diff
 ```
 
-
 :::
 
 ## `docOptions`
 
 Use these options to tweak some of the Docusaurus documentation features:
 
-- `pagination`: page buttons `Previous` and `Next`.
-- `toc`: page table of content.
-- `index`: index page for categories/groups, see [Docusaurus documentation](https://docusaurus.io/docs/sidebar/items#generated-index-page).
+- `frontMatter`: set custom front matter entries, see [Docusaurus documentation](https://docusaurus.io/docs/next/api/plugins/@docusaurus/plugin-content-docs#markdown-front-matter).
+- `index`: enable/disable index page for categories/groups, see [Docusaurus documentation](https://docusaurus.io/docs/sidebar/items#generated-index-page).
+- `pagination`: enable/disable page buttons `Previous` and `Next` [**deprecated**, see note below].
+- `toc`: enable/disable page table of content [**deprecated**, see note below].
 
-| Setting                 | CLI flag         | Default |
-| ----------------------- | ---------------- | ------- |
-| `docOptions.pagination` | `--noPagination` | `true`  |
-| `docOptions.toc`        | `--noToc`        | `true`  |
-| `docOptions.index`      | `--index`        | `false` |
+| Setting                  | CLI flag         | Default |
+| ------------------------ | ---------------- | ------- |
+| `docOptions.frontMatter` | _not supported_  | `{}`    |
+| `docOptions.index`       | `--index`        | `false` |
+| `docOptions.pagination`  | `--noPagination` | `true`  |
+| `docOptions.toc`         | `--noToc`        | `true`  |
 
 <br/>
 
@@ -78,8 +79,11 @@ plugins: [
         homepage: "./docs/swapi.md",
         // highlight-start
         docOptions: {
-          pagination: false, // disable buttons previous and next, same as CLI flag --noPagination
-          toc: false, // disable page table of content, same as CLI flag --noToc
+          frontMatter: {
+            pagination_next: null, // disable page navigation next
+            pagination_prev: null, // disable page navigation previous
+            hide_table_of_contents: true, // disable page table of content
+          },
           index: true, // enable generated index pages, same as CLI flag --index
         },
         // highlight-end
@@ -91,6 +95,33 @@ plugins: [
   ],
 ```
 
+<br/>
+
+:::warning[DEPRECATED]
+
+- **`docOptions.pagination`** (CLI flag `--noPagination`) has been replaced by `docOptions.frontMatter`:
+
+  ```js title="docusaurus.config.js"
+  docOptions: {
+   frontMatter: {
+     pagination_next: null, // disable page navigation next
+     pagination_prev: null, // disable page navigation previous
+   },
+  },
+  ```
+
+- **`docOptions.toc`** (CLI flag `--noToc`) has been replaced by `docOptions.frontMatter`:
+
+  ```js title="docusaurus.config.js"
+  docOptions: {
+   frontMatter: {
+     hide_table_of_contents: true, // disable page table of content
+   },
+  },
+  ```
+
+:::
+
 ## `groupByDirective`
 
 Use a GraphQL directive for creating documentation categories (see [documentation categories](/docs/advanced/group-by-directive)).
@@ -135,13 +166,13 @@ GraphQL schema loaders to use (see [schema loading](/docs/advanced/schema-loadin
 
 ## `metatags`
 
-Set page metadata  in `<html>`, `<head>` using [Docusaurus head metadata](https://docusaurus.io/docs/markdown-features/head-metadata).
+Set page metadata in `<html>`, `<head>` using [Docusaurus head metadata](https://docusaurus.io/docs/markdown-features/head-metadata).
 
 Meta tags are provided as list of metadata objects, eg `[{ name: "robots", content: "noindex" }]` for `<meta name="robots" content="noindex" />`.
 
-| Setting   | CLI flag        | Default |
-| --------- | --------------- | ------- |
-| `metatags` | _not supported_ | `[]`   |
+| Setting    | CLI flag        | Default |
+| ---------- | --------------- | ------- |
+| `metatags` | _not supported_ | `[]`    |
 
 <br/>
 
@@ -263,7 +294,7 @@ The `prettier` package has to be installed separately. If the package is not pre
 
 ## `runOnBuild`
 
-:::warning
+:::warning[EXPERIMENTAL]
 
 `runOnBuild` is an experimental feature, and it should not be used in production.
 
@@ -272,9 +303,9 @@ The `prettier` package has to be installed separately. If the package is not pre
 When set to `true` enables running doc generation on `docusaurus build`.
 If `false`, then the documentation can only be generated with the Docusaurus command `graphql-to-doc`.
 
-| Setting      | CLI flag | Default  |
-| ------------ | -------- | -------- |
-| `runOnBuild` | n/a      | `false`  |
+| Setting      | CLI flag | Default |
+| ------------ | -------- | ------- |
+| `runOnBuild` | n/a      | `false` |
 
 ## `rootPath`
 
diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts
index 788ffb9c..b01cc816 100644
--- a/packages/core/src/config.ts
+++ b/packages/core/src/config.ts
@@ -7,6 +7,8 @@ import type {
   ConfigOptions,
   ConfigPrintTypeOptions,
   CustomDirective,
+  DeprecatedCliOptions,
+  DeprecatedConfigDocOptions,
   DirectiveName,
   GroupByDirectiveOptions,
   LoaderOption,
@@ -19,6 +21,8 @@ import type {
 
 import { loadConfiguration } from "./graphql-config";
 
+import { log } from "@graphql-markdown/logger";
+
 export enum DiffMethod {
   NONE = "NONE",
   FORCE = "FORCE",
@@ -56,8 +60,7 @@ export const DEFAULT_OPTIONS: Required<
   diffMethod: DiffMethod.NONE as TypeDiffMethod,
   docOptions: {
     index: false,
-    pagination: true,
-    toc: true,
+    frontMatter: {},
   },
   groupByDirective: undefined,
   homepage: ASSET_HOMEPAGE_LOCATION,
@@ -206,21 +209,61 @@ export const getDiffMethod = (
     : (diff.toLocaleUpperCase() as TypeDiffMethod);
 };
 
+export const parseDeprecatedDocOptions = (
+  cliOpts: Maybe<DeprecatedCliOptions>,
+  configOptions: Maybe<DeprecatedConfigDocOptions>,
+): Partial<{
+  pagination_next: null;
+  pagination_prev: null;
+  hide_table_of_contents: boolean;
+}> => {
+  // deprecated, replaced by frontMatter
+  let pagination: Maybe<{ pagination_next: null; pagination_prev: null }>;
+  if (
+    (typeof cliOpts?.noPagination !== "undefined" && cliOpts.noPagination) ||
+    (typeof configOptions?.pagination !== "undefined" &&
+      !configOptions.pagination)
+  ) {
+    pagination = { pagination_next: null, pagination_prev: null };
+    log(
+      "Doc option `pagination` is deprecated. Use `frontMatter: { pagination_next: null, pagination_prev: null }` instead.",
+      "warn",
+    );
+  }
+
+  // deprecated, replaced by frontMatter
+  let toc: Maybe<{ hide_table_of_contents: boolean }>;
+  if (
+    typeof cliOpts?.noToc !== "undefined" ||
+    typeof configOptions?.toc !== "undefined"
+  ) {
+    toc = {
+      hide_table_of_contents:
+        cliOpts?.noToc === true || configOptions?.toc === false,
+    };
+    log(
+      "Doc option `toc` is deprecated. Use `frontMatter: { hide_table_of_contents: true | false }` instead.",
+      "warn",
+    );
+  }
+
+  return { ...pagination, ...toc };
+};
+
 export const getDocOptions = (
-  cliOpts: Maybe<CliOptions>,
-  configOptions: Maybe<ConfigDocOptions>,
+  cliOpts?: Maybe<CliOptions & DeprecatedCliOptions>,
+  configOptions?: Maybe<ConfigDocOptions & DeprecatedConfigDocOptions>,
 ): Required<ConfigDocOptions> => {
+  const deprecated = parseDeprecatedDocOptions(cliOpts, configOptions);
   return {
-    pagination:
-      (!cliOpts?.noPagination && configOptions?.pagination) ??
-      DEFAULT_OPTIONS.docOptions.pagination!,
-    toc:
-      (!cliOpts?.noToc && configOptions?.toc) ??
-      DEFAULT_OPTIONS.docOptions.toc!,
     index:
       // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
       (cliOpts?.index || configOptions?.index) ??
       DEFAULT_OPTIONS.docOptions.index!,
+    frontMatter: {
+      ...deprecated,
+      ...configOptions?.frontMatter,
+    },
   } as Required<ConfigDocOptions>;
 };
 
diff --git a/packages/core/src/renderer.ts b/packages/core/src/renderer.ts
index 7d14ff14..44911077 100644
--- a/packages/core/src/renderer.ts
+++ b/packages/core/src/renderer.ts
@@ -4,7 +4,6 @@ import type {
   Maybe,
   MDXString,
   Printer,
-  PrintTypeOptions,
   SchemaEntitiesGroupMap,
   SchemaEntity,
   TypeDeprecatedOption,
@@ -170,11 +169,7 @@ export class Renderer {
 
     let content: MDXString;
     try {
-      content = this.printer.printType(
-        fileName,
-        type,
-        this.options as PrintTypeOptions,
-      );
+      content = this.printer.printType(fileName, type, this.options);
       if (typeof content !== "string") {
         return undefined;
       }
diff --git a/packages/docusaurus/src/index.ts b/packages/docusaurus/src/index.ts
index 042d9138..ce4aa23a 100644
--- a/packages/docusaurus/src/index.ts
+++ b/packages/docusaurus/src/index.ts
@@ -1,6 +1,10 @@
 /* istanbul ignore file */
 import type { LoadContext, Plugin, PluginOptions } from "@docusaurus/types";
-import type { CliOptions, ConfigOptions } from "@graphql-markdown/types";
+import type {
+  CliOptions,
+  ConfigOptions,
+  ExperimentalConfigOptions,
+} from "@graphql-markdown/types";
 import { generateDocFromSchema, buildConfig } from "@graphql-markdown/core";
 import { Logger } from "@graphql-markdown/logger";
 
@@ -11,8 +15,7 @@ const DEFAULT_ID = "default" as const;
 
 export default function pluginGraphQLDocGenerator(
   _: LoadContext,
-  options: ConfigOptions &
-    Partial<PluginOptions> & { runOnBuild: boolean | undefined },
+  options: ConfigOptions & ExperimentalConfigOptions & Partial<PluginOptions>,
 ): Plugin {
   const loggerModule = require.resolve("@docusaurus/logger");
   Logger(loggerModule);
@@ -51,10 +54,8 @@ export default function pluginGraphQLDocGenerator(
           "File location for doc landing page",
         )
         .option("--noCode", "Disable code section for types")
-        .option("--noPagination", "Disable page navigation buttons")
         .option("--noParentType", "Disable parent type name as field prefix")
         .option("--noRelatedType", "Disable related types sections")
-        .option("--noToc", "Disable page table of content")
         .option("--noTypeBadges", "Disable badges for types")
         .option("--index", "Enable generated index for categories")
         .option("-f, --force", "Force document generation")
@@ -74,6 +75,12 @@ export default function pluginGraphQLDocGenerator(
           "Option for printing deprecated entities: `default`, `group` or `skip`",
         )
         .option("--pretty", "Prettify generated files")
+        // DEPRECATED options
+        .option("--noToc", "Disable page table of content [DEPRECATED]")
+        .option(
+          "--noPagination",
+          "Disable page navigation buttons [DEPRECATED]",
+        )
         .action(async (cliOptions: CliOptions) => {
           const config = await buildConfig(options, cliOptions, options.id);
           await generateDocFromSchema({
diff --git a/packages/graphql/docs/directive.md b/packages/graphql/docs/directive.md
index c58a5b3c..e8950981 100644
--- a/packages/graphql/docs/directive.md
+++ b/packages/graphql/docs/directive.md
@@ -8,7 +8,7 @@ Library supporting `customDirective` for directive based customization.
 
 ## Variables
 
-### WILDCARD\_DIRECTIVE
+### WILDCARD_DIRECTIVE
 
 ```ts
 const WILDCARD_DIRECTIVE: "*";
@@ -101,7 +101,7 @@ const map = getConstDirectiveMap(schema.getType("Test"), customDirectives);
 
 [packages/graphql/src/directive.ts:247](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/directive.ts#L247)
 
-***
+---
 
 ### getCustomDirectiveOptions()
 
@@ -150,7 +150,7 @@ const customDirectives = getCustomDirectiveOptions("testB", customDirectiveOptio
 
 [packages/graphql/src/directive.ts:76](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/directive.ts#L76)
 
-***
+---
 
 ### getCustomDirectives()
 
@@ -231,7 +231,7 @@ const customDirectives = getCustomDirectives(schemaMap, customDirectiveOptions);
 
 [packages/graphql/src/directive.ts:150](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/directive.ts#L150)
 
-***
+---
 
 ### isCustomDirective()
 
diff --git a/packages/graphql/docs/group.md b/packages/graphql/docs/group.md
index 098b7663..219c9b0f 100644
--- a/packages/graphql/docs/group.md
+++ b/packages/graphql/docs/group.md
@@ -67,19 +67,18 @@ const groupOptions = {
   fallback: "common",
   directive: "doc",
   field: "category",
-}
+};
 
 getGroupName(schema.getType("Bird"), groupOptions); // Expected result: "animal"
 
 getGroupName(schema.getType("Unicorn"), groupOptions); // Expected result: "common"
-
 ```
 
 #### Source
 
 [packages/graphql/src/group.ts:72](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/group.ts#L72)
 
-***
+---
 
 ### getGroups()
 
@@ -141,7 +140,7 @@ const groupOptions = {
   fallback: "common",
   directive: "doc",
   field: "category",
-}
+};
 
 const groupsMap = getGroups(schemaMap, groupOptions);
 
diff --git a/packages/graphql/docs/guard.md b/packages/graphql/docs/guard.md
index e4d56239..905fbcfb 100644
--- a/packages/graphql/docs/guard.md
+++ b/packages/graphql/docs/guard.md
@@ -36,7 +36,7 @@ the GraphQL type `T`.
 
 [packages/graphql/src/guard.ts:52](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/guard.ts#L52)
 
-***
+---
 
 ### isDeprecated()
 
@@ -66,7 +66,7 @@ an instance of `T`.
 
 [packages/graphql/src/guard.ts:70](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/guard.ts#L70)
 
-***
+---
 
 ### isGraphQLFieldType()
 
@@ -90,7 +90,7 @@ a GraphQL type.
 
 [packages/graphql/src/guard.ts:33](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/guard.ts#L33)
 
-***
+---
 
 ### isOperation()
 
diff --git a/packages/graphql/docs/introspection.md b/packages/graphql/docs/introspection.md
index 9db63784..378373d1 100644
--- a/packages/graphql/docs/introspection.md
+++ b/packages/graphql/docs/introspection.md
@@ -9,8 +9,8 @@ The entry point method is [getSchemaMap](introspection.md#getschemamap).
 
 ```ts
 _getFields<T, V>(
-   type, 
-   processor?, 
+   type,
+   processor?,
    fallback?): GraphQLFieldMap<unknown, unknown> | GraphQLInputFieldMap | V
 ```
 
@@ -48,7 +48,7 @@ a map of fields as k/v records, or `fallback` value if no fields available.
 
 [packages/graphql/src/introspection.ts:313](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L313)
 
-***
+---
 
 ### getDirective()
 
@@ -78,7 +78,7 @@ a list of GraphQL directives matching the set, else `false`.
 
 [packages/graphql/src/introspection.ts:222](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L222)
 
-***
+---
 
 ### getDirectiveLocationForASTPath()
 
@@ -98,7 +98,7 @@ getDirectiveLocationForASTPath(appliedTo): DirectiveLocation
 
 [packages/graphql/src/introspection.ts:111](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L111)
 
-***
+---
 
 ### getFields()
 
@@ -126,7 +126,7 @@ a list of fields of type object.
 
 [packages/graphql/src/introspection.ts:378](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L378)
 
-***
+---
 
 ### getOperation()
 
@@ -154,7 +154,7 @@ a map of fields as k/v records.
 
 [packages/graphql/src/introspection.ts:354](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L354)
 
-***
+---
 
 ### getSchemaMap()
 
@@ -241,14 +241,14 @@ const schemaTypeMap = getSchemaMap(schema);
 
 [packages/graphql/src/introspection.ts:488](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L488)
 
-***
+---
 
 ### getTypeDirectiveArgValue()
 
 ```ts
 getTypeDirectiveArgValue(
-   directive, 
-   node, 
+   directive,
+   node,
 argName): Maybe<Record<string, unknown>>
 ```
 
@@ -277,7 +277,7 @@ a record k/v with `argName` as key and the argument's value.
 
 [packages/graphql/src/introspection.ts:285](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L285)
 
-***
+---
 
 ### getTypeDirectiveValues()
 
@@ -307,7 +307,7 @@ a record k/v with arguments' name as keys and arguments' value.
 
 [packages/graphql/src/introspection.ts:254](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L254)
 
-***
+---
 
 ### getTypeFromSchema()
 
@@ -346,7 +346,7 @@ a map of GraphQL named types for the matching GraphQL type, or undefined if no m
 
 [packages/graphql/src/introspection.ts:59](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L59)
 
-***
+---
 
 ### getTypeName()
 
@@ -374,7 +374,7 @@ the type's name, or `defaultName`.
 
 [packages/graphql/src/introspection.ts:401](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L401)
 
-***
+---
 
 ### hasAstNode()
 
@@ -404,14 +404,14 @@ a GraphQL schema named type.
 
 [packages/graphql/src/introspection.ts:107](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L107)
 
-***
+---
 
 ### hasDirective()
 
 ```ts
 hasDirective(
-   entity, 
-   directives, 
+   entity,
+   directives,
    fallback): boolean
 ```
 
@@ -441,7 +441,7 @@ default value if the entity type is not a valid location for directives.
 
 [packages/graphql/src/introspection.ts:184](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/introspection.ts#L184)
 
-***
+---
 
 ### isValidDirectiveLocation()
 
diff --git a/packages/graphql/docs/loader.md b/packages/graphql/docs/loader.md
index b1067d31..8a23a92a 100644
--- a/packages/graphql/docs/loader.md
+++ b/packages/graphql/docs/loader.md
@@ -32,7 +32,10 @@ an `Error` if no loader has been loaded, or if an error occurred while importing
 #### Example
 
 ```js
-import { getDocumentLoaders, loadSchema } from "@graphql-markdown/utils/graphql"
+import {
+  getDocumentLoaders,
+  loadSchema,
+} from "@graphql-markdown/utils/graphql";
 
 const loaderList = {
   GraphQLFileLoader: "@graphql-tools/graphql-file-loader",
@@ -50,7 +53,7 @@ const schema = await loadSchema("schema.graphql", {
 
 [packages/graphql/src/loader.ts:106](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/graphql/src/loader.ts#L106)
 
-***
+---
 
 ### loadSchema()
 
@@ -81,7 +84,7 @@ a GraphQL schema.
 #### Example
 
 ```js
-import { loadSchema } from "@graphql-markdown/utils/graphql"
+import { loadSchema } from "@graphql-markdown/utils/graphql";
 
 const schema = await loadSchema("schema.graphql", {
   loaders: [new GraphQLFileLoader()],
diff --git a/packages/graphql/docs/relation.md b/packages/graphql/docs/relation.md
index 35ff0353..56c7a33d 100644
--- a/packages/graphql/docs/relation.md
+++ b/packages/graphql/docs/relation.md
@@ -40,7 +40,7 @@ a record map of fields and arguments relations.
 
 [packages/types/src/graphql.d.ts:78](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/types/src/graphql.d.ts#L78)
 
-***
+---
 
 ### getRelationOfImplementation()
 
@@ -74,7 +74,7 @@ a record map of unions or interfaces relations.
 
 [packages/types/src/graphql.d.ts:78](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/types/src/graphql.d.ts#L78)
 
-***
+---
 
 ### getRelationOfInterface()
 
@@ -108,7 +108,7 @@ a record map of interfaces relations.
 
 [packages/types/src/graphql.d.ts:78](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/types/src/graphql.d.ts#L78)
 
-***
+---
 
 ### getRelationOfReturn()
 
@@ -142,7 +142,7 @@ a record map of operations relations.
 
 [packages/types/src/graphql.d.ts:78](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/types/src/graphql.d.ts#L78)
 
-***
+---
 
 ### getRelationOfUnion()
 
diff --git a/packages/helpers/docs/directives/descriptor.md b/packages/helpers/docs/directives/descriptor.md
index 978def8d..845ab828 100644
--- a/packages/helpers/docs/directives/descriptor.md
+++ b/packages/helpers/docs/directives/descriptor.md
@@ -12,8 +12,8 @@ Custom directive `descriptor` helper.
 
 ```ts
 directiveDescriptor(
-   directive, 
-   type?, 
+   directive,
+   type?,
    descriptionTemplate?): string
 ```
 
@@ -57,44 +57,55 @@ const directive = new GraphQLDirective({
   },
 });
 
-const type = new GraphQLScalarType<string>({
-  name: "FooBar",
-  astNode: {
-    kind: Kind.SCALAR_TYPE_DEFINITION,
-    name: { kind: Kind.NAME, value: "FooBar" },
-    directives: [
-      {
-        kind: Kind.DIRECTIVE,
-        name: { kind: Kind.NAME, value: "version" },
-        arguments: [
-          {
-            kind: Kind.ARGUMENT,
-            name: { kind: Kind.NAME, value: "major" },
-            value: { kind: Kind.INT, value: "2" },
-          },
-          {
-            kind: Kind.ARGUMENT,
-            name: { kind: Kind.NAME, value: "minor" },
-            value: { kind: Kind.INT, value: "1" },
-          },
-          {
-            kind: Kind.ARGUMENT,
-            name: { kind: Kind.NAME, value: "patch" },
-            value: { kind: Kind.INT, value: "3" },
-          },
-        ],
-      },
-    ],
-  },
-});
+const type =
+  new GraphQLScalarType() <
+  string >
+  {
+    name: "FooBar",
+    astNode: {
+      kind: Kind.SCALAR_TYPE_DEFINITION,
+      name: { kind: Kind.NAME, value: "FooBar" },
+      directives: [
+        {
+          kind: Kind.DIRECTIVE,
+          name: { kind: Kind.NAME, value: "version" },
+          arguments: [
+            {
+              kind: Kind.ARGUMENT,
+              name: { kind: Kind.NAME, value: "major" },
+              value: { kind: Kind.INT, value: "2" },
+            },
+            {
+              kind: Kind.ARGUMENT,
+              name: { kind: Kind.NAME, value: "minor" },
+              value: { kind: Kind.INT, value: "1" },
+            },
+            {
+              kind: Kind.ARGUMENT,
+              name: { kind: Kind.NAME, value: "patch" },
+              value: { kind: Kind.INT, value: "3" },
+            },
+          ],
+        },
+      ],
+    },
+  };
 
-directiveDescriptor(directive, type, "${description} is ${major}.${minor}.${patch}");
+directiveDescriptor(
+  directive,
+  type,
+  "${description} is ${major}.${minor}.${patch}",
+);
 // Expected result: "Min version is 2.1.3"
 
 directiveDescriptor(directive, type);
 // Expected result: "Min version"
 
-directiveDescriptor(directive, type, "Version should be at least ^${major}.${minor}.${patch}");
+directiveDescriptor(
+  directive,
+  type,
+  "Version should be at least ^${major}.${minor}.${patch}",
+);
 // Expected result: "Version should be at least ^2.1.3"
 ```
 
diff --git a/packages/helpers/docs/directives/tag.md b/packages/helpers/docs/directives/tag.md
index 75b73bcb..970f3be7 100644
--- a/packages/helpers/docs/directives/tag.md
+++ b/packages/helpers/docs/directives/tag.md
@@ -12,8 +12,8 @@ Custom directive `tag` helper.
 
 ```ts
 directiveTag(
-   directive, 
-   type?, 
+   directive,
+   type?,
    classname?): Badge
 ```
 
@@ -52,19 +52,22 @@ const directive = new GraphQLDirective({
   locations: [],
 });
 
-const type = new GraphQLScalarType<string>({
-  name: "FooBar",
-  astNode: {
-    kind: Kind.SCALAR_TYPE_DEFINITION,
-    name: { kind: Kind.NAME, value: "FooBar" },
-    directives: [
-      {
-        kind: Kind.DIRECTIVE,
-        name: { kind: Kind.NAME, value: "auth" },
-      },
-    ],
-  },
-});
+const type =
+  new GraphQLScalarType() <
+  string >
+  {
+    name: "FooBar",
+    astNode: {
+      kind: Kind.SCALAR_TYPE_DEFINITION,
+      name: { kind: Kind.NAME, value: "FooBar" },
+      directives: [
+        {
+          kind: Kind.DIRECTIVE,
+          name: { kind: Kind.NAME, value: "auth" },
+        },
+      ],
+    },
+  };
 
 directiveTag(directive, type);
 // Expected result: { text: "@auth", classname: "badge--secondary" }
diff --git a/packages/helpers/docs/utils/interpolate.md b/packages/helpers/docs/utils/interpolate.md
index 0466507d..03c2587c 100644
--- a/packages/helpers/docs/utils/interpolate.md
+++ b/packages/helpers/docs/utils/interpolate.md
@@ -8,8 +8,8 @@ Helpers utility functions library.
 
 ```ts
 getObjPath(
-   path, 
-   obj, 
+   path,
+   obj,
    fallback): unknown
 ```
 
@@ -38,7 +38,7 @@ the property value if the path is resolved, else returns the `fallback` value.
 #### Example
 
 ```js
-import { getObjPath } from '@graphql-markdown/utils/object';
+import { getObjPath } from "@graphql-markdown/utils/object";
 
 getObjPath("foo.bar", { foo: { bar: 42 } }); // Returns 42
 
@@ -49,14 +49,14 @@ getObjPath("foo.bak", { foo: { bar: 42 } }, "fallback"); // Returns "fallback"
 
 [utils/interpolate.ts:31](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/helpers/src/utils/interpolate.ts#L31)
 
-***
+---
 
 ### interpolate()
 
 ```ts
 interpolate(
-   template, 
-   variables, 
+   template,
+   variables,
    fallback?): string
 ```
 
diff --git a/packages/logger/docs/exports.md b/packages/logger/docs/exports.md
index 9010e020..9d658a8d 100644
--- a/packages/logger/docs/exports.md
+++ b/packages/logger/docs/exports.md
@@ -106,7 +106,7 @@ log("Info message", "info"); // Expected Docusaurus log output "Info message"
 
 [index.ts:45](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/logger/src/index.ts#L45)
 
-***
+---
 
 ### log()
 
@@ -122,14 +122,14 @@ Logs a message by calling the active logger instance.
 
 a string to be logged.
 
-▪ **level**: 
-  \| `"debug"`
-  \| `"error"`
-  \| `"info"`
-  \| `"log"`
-  \| `"success"`
-  \| `"warn"`
-  \| [`LogLevel`](exports.md#loglevel)= `LogLevel.info`
+▪ **level**:
+\| `"debug"`
+\| `"error"`
+\| `"info"`
+\| `"log"`
+\| `"success"`
+\| `"warn"`
+\| [`LogLevel`](exports.md#loglevel)= `LogLevel.info`
 
 optional log level, `"info"` by default.
 
diff --git a/packages/printer-legacy/src/const/options.ts b/packages/printer-legacy/src/const/options.ts
index c4e8e81a..2443741c 100644
--- a/packages/printer-legacy/src/const/options.ts
+++ b/packages/printer-legacy/src/const/options.ts
@@ -1,9 +1,9 @@
 import type {
   CollapsibleOption,
+  FrontMatterOptions,
   GraphQLDirective,
   GraphQLSchema,
   Maybe,
-  PrintTypeHeaderOptions,
   PrintTypeOptions,
   PrinterConfigPrintTypeOptions,
   SchemaEntitiesGroupMap,
@@ -52,7 +52,7 @@ export const DEFAULT_OPTIONS: Required<
   collapsible: undefined,
   customDirectives: {},
   groups: undefined,
-  header: { toc: true, pagination: true } as Required<PrintTypeHeaderOptions>,
+  frontMatter: {} as FrontMatterOptions,
   level: undefined,
   metatags: [],
   onlyDocDirectives: [],
diff --git a/packages/printer-legacy/src/printer.ts b/packages/printer-legacy/src/printer.ts
index a2e838b5..e64a75fd 100644
--- a/packages/printer-legacy/src/printer.ts
+++ b/packages/printer-legacy/src/printer.ts
@@ -134,19 +134,16 @@ export class Printer implements IPrinter {
     title: string,
     options: PrintTypeOptions,
   ): string => {
-    const { toc, pagination } = options.header ?? DEFAULT_OPTIONS.header!;
-    const paginationButtons = pagination!
-      ? []
-      : ["pagination_next: null", "pagination_prev: null"];
+    const frontMatter = options.frontMatter ?? DEFAULT_OPTIONS.frontMatter!;
 
-    const header = [
-      FRONT_MATTER,
-      `id: ${id}`,
-      `title: ${title}`,
-      `hide_table_of_contents: ${!toc}`,
-      ...paginationButtons,
-      FRONT_MATTER,
-    ];
+    const header: string[] = [FRONT_MATTER, `id: ${id}`, `title: ${title}`];
+
+    if (typeof frontMatter === "object") {
+      for (const [key, value] of Object.entries(frontMatter)) {
+        header.push(`${key}: ${value}`);
+      }
+    }
+    header.push(FRONT_MATTER);
 
     return header.join(MARKDOWN_EOL);
   };
diff --git a/packages/types/package.json b/packages/types/package.json
index 37faa9b3..1dd2ecbb 100644
--- a/packages/types/package.json
+++ b/packages/types/package.json
@@ -21,7 +21,7 @@
   "types": "src/index.d.ts",
   "devDependencies": {
     "@graphql-tools/load": "8.0.1",
-    "@graphql-tools/utils":"10.0.11",
+    "@graphql-tools/utils": "10.0.11",
     "graphql-config": "5.0.3"
   },
   "publishConfig": {
diff --git a/packages/types/src/core.d.ts b/packages/types/src/core.d.ts
index 1e3a1faf..919051a3 100644
--- a/packages/types/src/core.d.ts
+++ b/packages/types/src/core.d.ts
@@ -3,8 +3,14 @@ import type { BaseLoaderOptions } from "@graphql-tools/utils";
 
 import type { CustomDirective, DirectiveName, GraphQLSchema } from ".";
 
+export type FrontMatterOptions = Record<string, unknown>;
+
 export interface ConfigDocOptions {
   index?: boolean;
+  frontMatter: Maybe<FrontMatterOptions>;
+}
+
+export interface DeprecatedConfigDocOptions {
   pagination?: boolean;
   toc?: boolean;
 }
@@ -29,7 +35,7 @@ export interface ConfigOptions {
   baseURL?: Maybe<string>;
   customDirective?: Maybe<CustomDirective>;
   diffMethod?: Maybe<TypeDiffMethod>;
-  docOptions?: Maybe<ConfigDocOptions>;
+  docOptions?: Maybe<ConfigDocOptions & DeprecatedConfigDocOptions>;
   groupByDirective?: Maybe<GroupByDirectiveOptions>;
   homepage?: Maybe<string>;
   id?: Maybe<string>;
@@ -46,6 +52,10 @@ export interface ConfigOptions {
   tmpDir?: Maybe<string>;
 }
 
+export interface ExperimentalConfigOptions {
+  runOnBuild: boolean | undefined;
+}
+
 export interface CliOptions {
   base?: string;
   deprecated?: TypeDeprecatedOption;
@@ -56,10 +66,8 @@ export interface CliOptions {
   index?: boolean;
   link?: string;
   noCode?: boolean;
-  noPagination?: boolean;
   noParentType?: boolean;
   noRelatedType?: boolean;
-  noToc?: boolean;
   noTypeBadges?: boolean;
   pretty?: boolean;
   root?: string;
@@ -69,6 +77,11 @@ export interface CliOptions {
   tmp?: string;
 }
 
+export interface DeprecatedCliOptions {
+  noPagination?: boolean;
+  noToc?: boolean;
+}
+
 export type Options = Omit<
   ConfigOptions,
   "homepage" | "pretty" | "rootPath" | "schema"
diff --git a/packages/types/src/printer.d.ts b/packages/types/src/printer.d.ts
index b2c8286f..83789e63 100644
--- a/packages/types/src/printer.d.ts
+++ b/packages/types/src/printer.d.ts
@@ -6,6 +6,7 @@ import type {
   CustomDirectiveMap,
   ConfigPrintTypeOptions,
   GraphQLDirective,
+  FrontMatterOptions,
 } from ".";
 
 export type RootTypeName =
@@ -39,19 +40,14 @@ export interface CollapsibleOption {
   dataClose: string;
 }
 
-export interface PrintTypeHeaderOptions {
-  pagination?: boolean;
-  toc?: boolean;
-}
-
 export interface PrintTypeOptions {
   basePath: string;
   codeSection?: Maybe<boolean>;
   collapsible?: Maybe<CollapsibleOption>;
   customDirectives?: Maybe<CustomDirectiveMap>;
   deprecated?: Maybe<TypeDeprecatedOption>;
+  frontMatter?: Maybe<FrontMatterOptions>;
   groups?: Maybe<SchemaEntitiesGroupMap>;
-  header?: Maybe<PrintTypeHeaderOptions>;
   level?: Maybe<SectionLevelValue>;
   metatags?: Maybe<Record<string, string>[]>;
   onlyDocDirectives?: GraphQLDirective[];
@@ -139,15 +135,15 @@ export abstract class IPrinter {
   static printType(
     name: string,
     type: unknown,
-    options: Maybe<Partial<PrinterConfig & PrinterOptions>>,
+    options?: Maybe<Partial<PrintTypeOptions>>,
   ): MDXString;
 }
 export type Printer = typeof IPrinter;
 
 export interface PrinterConfig {
-  schema: Maybe<GraphQLSchema>;
   baseURL: string;
   linkRoot: string;
+  schema: Maybe<GraphQLSchema>;
 }
 
 export interface PrinterOptions {
diff --git a/packages/utils/docs/array.md b/packages/utils/docs/array.md
index 84b24396..66bb30b2 100644
--- a/packages/utils/docs/array.md
+++ b/packages/utils/docs/array.md
@@ -33,14 +33,14 @@ an array of object values with `name` as key, or `undefined` if `list` is not a
 #### Example
 
 ```js
-import { convertArrayToMapObject } from '@graphql-markdown/utils/array';
+import { convertArrayToMapObject } from "@graphql-markdown/utils/array";
 
 convertArrayToMapObject([
-    { name: true },
-    { name: "test" },
-    { name: 123 },
-    { name2: 1234 },
-  ]);
+  { name: true },
+  { name: "test" },
+  { name: 123 },
+  { name2: 1234 },
+]);
 
 // Expected result: {
 //   true: { name: true },
@@ -53,7 +53,7 @@ convertArrayToMapObject([
 
 [array.ts:76](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/array.ts#L76)
 
-***
+---
 
 ### toArray()
 
@@ -78,15 +78,15 @@ an array of object values, or `undefined` if `recordMap` is not a valid object.
 #### Example
 
 ```js
-import { toArray } from '@graphql-markdown/utils/array';
+import { toArray } from "@graphql-markdown/utils/array";
 
 toArray({
-    bool: true,
-    string: "test",
-    number: 123,
-    array: ["one", "two"],
-    child: { key: "value" },
-  });
+  bool: true,
+  string: "test",
+  number: 123,
+  array: ["one", "two"],
+  child: { key: "value" },
+});
 
 // Expected result: [true, "test", 123, ["one", "two"], { key: "value" }]
 ```
diff --git a/packages/utils/docs/fs.md b/packages/utils/docs/fs.md
index ef5e4cc8..ee3e9c89 100644
--- a/packages/utils/docs/fs.md
+++ b/packages/utils/docs/fs.md
@@ -25,9 +25,9 @@ folder structure in path format.
 #### Example
 
 ```js
-import { ensureDir } from '@graphql-markdown/utils/fs';
+import { ensureDir } from "@graphql-markdown/utils/fs";
 
-await ensureDir("./.temp/local")
+await ensureDir("./.temp/local");
 
 // Creates both folders if they do not exists.
 ```
@@ -36,7 +36,7 @@ await ensureDir("./.temp/local")
 
 [fs.ts:57](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/fs.ts#L57)
 
-***
+---
 
 ### fileExists()
 
@@ -61,9 +61,9 @@ file or folder location.
 #### Example
 
 ```js
-import { fileExists } from '@graphql-markdown/utils/fs';
+import { fileExists } from "@graphql-markdown/utils/fs";
 
-await fileExists("./.temp/local")
+await fileExists("./.temp/local");
 
 // Expected true if path is valid, false if not
 ```
@@ -72,14 +72,14 @@ await fileExists("./.temp/local")
 
 [fs.ts:32](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/fs.ts#L32)
 
-***
+---
 
 ### saveFile()
 
 ```ts
 saveFile(
-   location, 
-   content, 
+   location,
+   content,
 prettify?): Promise<void>
 ```
 
@@ -110,9 +110,9 @@ optional callback function for prettifying the content.
 #### Example
 
 ```js
-import { saveFile } from '@graphql-markdown/utils/fs';
+import { saveFile } from "@graphql-markdown/utils/fs";
 
-await saveFile("./.temp/local.md", "foobar")
+await saveFile("./.temp/local.md", "foobar");
 
 // Created .temp folder if it does not exists, and save data into local.md
 ```
diff --git a/packages/utils/docs/object.md b/packages/utils/docs/object.md
index 981ba235..85dd313c 100644
--- a/packages/utils/docs/object.md
+++ b/packages/utils/docs/object.md
@@ -27,7 +27,7 @@ the key/value record object.
 #### Example
 
 ```js
-import { isEmpty } from '@graphql-markdown/utils/object';
+import { isEmpty } from "@graphql-markdown/utils/object";
 
 const obj = {
   bool: true,
diff --git a/packages/utils/docs/prettier.md b/packages/utils/docs/prettier.md
index 3aeb9c6f..94bf9c58 100644
--- a/packages/utils/docs/prettier.md
+++ b/packages/utils/docs/prettier.md
@@ -40,7 +40,7 @@ https://prettier.io/docs/en/options#parser for the list of parsers.
 
 [prettier.ts:29](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/prettier.ts#L29)
 
-***
+---
 
 ### prettifyJavascript()
 
@@ -74,7 +74,7 @@ Same as `prettify(content, "babel")`.
 
 [prettier.ts:82](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/prettier.ts#L82)
 
-***
+---
 
 ### prettifyMarkdown()
 
diff --git a/packages/utils/docs/string.md b/packages/utils/docs/string.md
index 54102c8a..7a51aefb 100644
--- a/packages/utils/docs/string.md
+++ b/packages/utils/docs/string.md
@@ -37,7 +37,7 @@ capitalize("the quick Brown Fox");
 
 [string.ts:216](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/string.ts#L216)
 
-***
+---
 
 ### escapeMDX()
 
@@ -72,7 +72,7 @@ escapeMDX("{MDX} <special> characters");
 
 [string.ts:172](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/string.ts#L172)
 
-***
+---
 
 ### firstUppercase()
 
@@ -107,7 +107,7 @@ firstUppercase("the quick Brown Fox");
 
 [string.ts:192](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/string.ts#L192)
 
-***
+---
 
 ### kebabCase()
 
@@ -142,7 +142,7 @@ kebabCase("The quick brown Fox");
 
 [string.ts:259](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/string.ts#L259)
 
-***
+---
 
 ### prune()
 
@@ -183,7 +183,7 @@ prune(text, "**");
 
 [string.ts:58](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/string.ts#L58)
 
-***
+---
 
 ### replaceDiacritics()
 
@@ -205,7 +205,7 @@ the string to be transformed.
 
 a string with diacritic characters replaced, or an empty string if `str` is not a valid string.
 
- *
+-
 
 #### Example
 
@@ -223,7 +223,7 @@ replaceDiacritics("Âéêś"); // Expected result: "Aees"
 
 [string.ts:27](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/string.ts#L27)
 
-***
+---
 
 ### slugify()
 
@@ -245,7 +245,7 @@ Alias of [kebabCase](string.md#kebabcase).
 
 [string.ts:259](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/string.ts#L259)
 
-***
+---
 
 ### startCase()
 
@@ -280,15 +280,15 @@ startCase("the quick Brown Fox");
 
 [string.ts:238](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/string.ts#L238)
 
-***
+---
 
 ### stringCaseBuilder()
 
 ```ts
 stringCaseBuilder(
-   str, 
-   transformation?, 
-   separator?, 
+   str,
+   transformation?,
+   separator?,
    splitter?): string
 ```
 
@@ -337,7 +337,7 @@ stringCaseBuilder(text, transformation, " ");
 
 [string.ts:100](https://github.com/graphql-markdown/graphql-markdown/blob/main/packages/utils/src/string.ts#L100)
 
-***
+---
 
 ### toHTMLUnicode()
 
diff --git a/typedoc.base.json b/typedoc.base.json
index 338b685d..31615c30 100644
--- a/typedoc.base.json
+++ b/typedoc.base.json
@@ -20,5 +20,5 @@
   "validation": {
     "notDocumented": true
   },
-  "sourceLinkExternal": true,
+  "sourceLinkExternal": true
 }
diff --git a/website/package.json b/website/package.json
index dd6c9598..b92c7463 100644
--- a/website/package.json
+++ b/website/package.json
@@ -21,7 +21,7 @@
   },
   "overrides": {
     "@cmfcmf/docusaurus-search-local": {
-        "@docusaurus/core": "^3.0.0-rc.0"
+      "@docusaurus/core": "^3.0.0-rc.0"
     }
   },
   "devDependencies": {
diff --git a/website/src/css/custom.css b/website/src/css/custom.css
index ab7709be..91fdf00b 100644
--- a/website/src/css/custom.css
+++ b/website/src/css/custom.css
@@ -95,7 +95,13 @@ span.deprecated::after {
 div[class^="announcementBar_"] {
   --site-announcement-bar-stripe-color1: #ffd7ff;
   --site-announcement-bar-stripe-color2: #e6ffd1;
-  background: repeating-linear-gradient(55deg, var(--site-announcement-bar-stripe-color1), var(--site-announcement-bar-stripe-color1) 20px, var(--site-announcement-bar-stripe-color2) 10px, var(--site-announcement-bar-stripe-color2) 40px);
+  background: repeating-linear-gradient(
+    55deg,
+    var(--site-announcement-bar-stripe-color1),
+    var(--site-announcement-bar-stripe-color1) 20px,
+    var(--site-announcement-bar-stripe-color2) 10px,
+    var(--site-announcement-bar-stripe-color2) 40px
+  );
   color: black !important;
   font-weight: 500;
 }


Test patch:
diff --git a/packages/core/tests/unit/config.test.ts b/packages/core/tests/unit/config.test.ts
index 0ecc5297..17383207 100644
--- a/packages/core/tests/unit/config.test.ts
+++ b/packages/core/tests/unit/config.test.ts
@@ -18,19 +18,30 @@ import {
   DiffMethod,
   getCustomDirectives,
   getDocDirective,
+  getDocOptions,
   getOnlyDocDirectives,
   getSkipDocDirectives,
   getVisibilityDirectives,
+  parseDeprecatedDocOptions,
   parseGroupByOption,
 } from "../../src/config";
 
 jest.mock("@graphql-markdown/utils");
 
 describe("config", () => {
+  beforeAll(() => {
+    Object.assign(global, { logger: global.console });
+  });
+
   afterEach(() => {
+    jest.restoreAllMocks();
     jest.resetAllMocks();
   });
 
+  afterAll(() => {
+    delete global.logger;
+  });
+
   describe("getSkipDocDirectives", () => {
     test("returns a list of directive names", () => {
       expect.hasAssertions();
@@ -217,8 +228,6 @@ describe("config", () => {
         pretty: true,
         docOptions: {
           index: false,
-          pagination: false,
-          toc: false,
         },
         printTypeOptions: {
           codeSection: false,
@@ -246,7 +255,7 @@ describe("config", () => {
         baseURL: configFileOpts.baseURL,
         customDirective: configFileOpts.customDirective,
         diffMethod: configFileOpts.diffMethod,
-        docOptions: configFileOpts.docOptions,
+        docOptions: { ...configFileOpts.docOptions, frontMatter: {} },
         groupByDirective: configFileOpts.groupByDirective,
         homepageLocation: configFileOpts.homepage,
         id: DEFAULT_OPTIONS.id,
@@ -285,8 +294,6 @@ describe("config", () => {
           fallback: "Common",
         },
         docOptions: {
-          pagination: true,
-          toc: true,
           index: true,
         },
       };
@@ -300,8 +307,6 @@ describe("config", () => {
         index: true,
         link: "/cli",
         noCode: true,
-        noPagination: true,
-        noToc: true,
         only: "@public",
         pretty: true,
         root: "cli",
@@ -330,9 +335,8 @@ describe("config", () => {
         schemaLocation: cliOpts.schema,
         tmpDir: cliOpts.tmp,
         docOptions: {
-          pagination: !cliOpts.noPagination,
-          toc: !cliOpts.noToc,
-          index: cliOpts.index,
+          frontMatter: {},
+          index: true,
         },
         printTypeOptions: {
           ...DEFAULT_OPTIONS.printTypeOptions,
@@ -546,4 +550,115 @@ describe("config", () => {
       `);
     });
   });
+
+  describe("getDocOptions()", () => {
+    test("returns object with default index and default frontMatter", () => {
+      expect.assertions(2);
+
+      const { index, frontMatter } = getDocOptions();
+
+      expect(index).toBeFalsy();
+      expect(frontMatter).toStrictEqual({});
+    });
+
+    test("returns object with parsed index from cli", () => {
+      expect.assertions(2);
+
+      const { index, frontMatter } = getDocOptions({ index: true });
+
+      expect(index).toBeTruthy();
+      expect(frontMatter).toStrictEqual({});
+    });
+
+    test("returns object with parsed index from config", () => {
+      expect.assertions(2);
+
+      const { index, frontMatter } = getDocOptions(undefined, {
+        index: true,
+        frontMatter: undefined,
+      });
+
+      expect(index).toBeTruthy();
+      expect(frontMatter).toStrictEqual({});
+    });
+
+    test("returns object with parsed frontMatter from config", () => {
+      expect.assertions(2);
+
+      const { index, frontMatter } = getDocOptions(undefined, {
+        frontMatter: { draft: true },
+      });
+
+      expect(index).toBeFalsy();
+      expect(frontMatter).toStrictEqual({ draft: true });
+    });
+  });
+
+  describe("parseDeprecatedDocOptions", () => {
+    test("returns empty object if no deprecated option is used", () => {
+      expect.hasAssertions();
+
+      const cliOpt = {},
+        configOptions = undefined;
+
+      expect(parseDeprecatedDocOptions(cliOpt, configOptions)).toStrictEqual(
+        {},
+      );
+    });
+
+    test.each([
+      {
+        cliOpt: { noPagination: true },
+        configOptions: { frontMatter: undefined },
+      },
+      {
+        cliOpt: {},
+        configOptions: { pagination: false, frontMatter: undefined },
+      },
+    ])(
+      "returns pagination nulled if pagination option is disabled",
+      ({ cliOpt, configOptions }) => {
+        expect.hasAssertions();
+
+        const spyConsole = jest
+          .spyOn(global.console, "warn")
+          .mockImplementation(() => {});
+
+        expect(parseDeprecatedDocOptions(cliOpt, configOptions)).toStrictEqual({
+          pagination_next: null,
+          pagination_prev: null,
+        });
+        expect(spyConsole).toHaveBeenCalledWith(
+          "Doc option `pagination` is deprecated. Use `frontMatter: { pagination_next: null, pagination_prev: null }` instead.",
+        );
+      },
+    );
+
+    test.each([
+      {
+        cliOpt: { noToc: true },
+        configOptions: { frontMatter: undefined },
+      },
+      {
+        cliOpt: {},
+        configOptions: { toc: false, frontMatter: undefined },
+      },
+    ])(
+      "returns hide_table_of_contents set to true if toc option is disabled",
+      ({ cliOpt, configOptions }) => {
+        expect.hasAssertions();
+
+        const spyConsole = jest
+          .spyOn(global.console, "warn")
+          .mockImplementation(() => {});
+
+        expect(parseDeprecatedDocOptions(cliOpt, configOptions)).toStrictEqual({
+          hide_table_of_contents: true,
+        });
+        expect(spyConsole).toHaveBeenCalledWith(
+          "Doc option `toc` is deprecated. Use `frontMatter: { hide_table_of_contents: true | false }` instead.",
+        );
+      },
+    );
+  });
 });
diff --git a/packages/core/tests/unit/generator.test.ts b/packages/core/tests/unit/generator.test.ts
index 9d0f4a76..ff509200 100644
--- a/packages/core/tests/unit/generator.test.ts
+++ b/packages/core/tests/unit/generator.test.ts
@@ -43,8 +43,6 @@ describe("generator", () => {
       diffMethod: "diff method",
       docOptions: {
         index: true,
-        pagination: true,
-        toc: true,
       },
       printTypeOptions: {
         codeSection: true,
diff --git a/packages/core/tests/unit/renderer.test.ts b/packages/core/tests/unit/renderer.test.ts
index 7a1a93e8..6b497bbb 100644
--- a/packages/core/tests/unit/renderer.test.ts
+++ b/packages/core/tests/unit/renderer.test.ts
@@ -388,6 +388,7 @@ describe("renderer", () => {
 
         const spy = jest.spyOn(rendererInstance, "generateCategoryMetafile");
         jest.replaceProperty(rendererInstance, "options", {
+          frontMatter: undefined,
           deprecated: "group",
         });
         jest.spyOn(GraphQL, "isDeprecated").mockReturnValue(true);
@@ -415,6 +416,7 @@ describe("renderer", () => {
 
         const spy = jest.spyOn(rendererInstance, "generateCategoryMetafile");
         jest.replaceProperty(rendererInstance, "options", {
+          frontMatter: undefined,
           deprecated: "group",
         });
         jest.spyOn(GraphQL, "isDeprecated").mockReturnValue(false);
@@ -436,6 +438,7 @@ describe("renderer", () => {
 
         const spy = jest.spyOn(rendererInstance, "generateCategoryMetafile");
         jest.replaceProperty(rendererInstance, "options", {
+          frontMatter: undefined,
           deprecated: "default",
         });
         jest.spyOn(GraphQL, "isDeprecated").mockReturnValue(false);
@@ -457,6 +460,7 @@ describe("renderer", () => {
 
         const spy = jest.spyOn(rendererInstance, "generateCategoryMetafile");
         jest.replaceProperty(rendererInstance, "options", {
+          frontMatter: undefined,
           deprecated: "group",
         });
         jest.replaceProperty(rendererInstance, "group", {
diff --git a/packages/docusaurus/tests/__data__/anilist.md b/packages/docusaurus/tests/__data__/anilist.md
index 7c6ac057..7152735f 100644
--- a/packages/docusaurus/tests/__data__/anilist.md
+++ b/packages/docusaurus/tests/__data__/anilist.md
@@ -29,12 +29,14 @@ This documentation has been automatically generated using [AniList APIv2](https:
       "options": { "method": "POST" }
     }
   },
+  "docOptions": {
+    "frontMatter": {
+      "pagination_next": null,
+      "pagination_prev": null
+    }
+  },
   "printTypeOptions": {
     "deprecated": "group"
-  },
-  "docOptions": {
-    "pagination": false,
-    "toc": false
   }
 }
 ```
@@ -54,11 +56,12 @@ extensions:
         module: "@graphql-tools/url-loader"
         options:
           method: POST
+    docOptions:
+      frontMatter:
+        pagination_next: null,
+        pagination_prev: null,
     printTypeOptions:
       deprecated: group
-    docOptions:
-      pagination: false
-      toc: false
 ```
 
 </TabItem>
@@ -70,7 +73,6 @@ npx docusaurus graphql-to-doc \
     --schema https://graphql.anilist.co/ \
     --base . \
     --link /examples/default \
-    --noPagination \
     --deprecated group
 ```
 
diff --git a/packages/docusaurus/tests/__data__/docusaurus2-graphql-doc-generator-groups.config.js b/packages/docusaurus/tests/__data__/docusaurus2-graphql-doc-generator-groups.config.js
index 634863c2..e5e4e8d4 100644
--- a/packages/docusaurus/tests/__data__/docusaurus2-graphql-doc-generator-groups.config.js
+++ b/packages/docusaurus/tests/__data__/docusaurus2-graphql-doc-generator-groups.config.js
@@ -9,7 +9,7 @@ module.exports = {
   id: "schema_with_grouping",
   schema: "data/schema_with_grouping.graphql",
   rootPath: "./docs",
-  linkRoot: "/examples/default",
+  linkRoot: "/examples/group-by",
   baseURL: ".",
   diffMethod: "SCHEMA-HASH",
   loaders: { GraphQLFileLoader: "@graphql-tools/graphql-file-loader" },
@@ -18,15 +18,14 @@ module.exports = {
     field: "category",
     fallback: "Common",
   },
-  docOptions: {
-    pagination: true,
-    toc: true,
-  },
   printTypeOptions: {
     parentTypePrefix: false,
     relatedTypeSection: false,
     typeBadges: true,
   },
+  docOptions: {
+    index: true,
+  },
   customDirective: {
     beta: {
       tag: (directive) => ({
diff --git a/packages/docusaurus/tests/__data__/docusaurus2-graphql-doc-generator.config.js b/packages/docusaurus/tests/__data__/docusaurus2-graphql-doc-generator.config.js
index 4b74491f..e6a16477 100644
--- a/packages/docusaurus/tests/__data__/docusaurus2-graphql-doc-generator.config.js
+++ b/packages/docusaurus/tests/__data__/docusaurus2-graphql-doc-generator.config.js
@@ -1,7 +1,7 @@
 module.exports = {
   schema: "data/tweet.graphql",
   rootPath: "./docs",
-  linkRoot: "/examples/group-by",
+  linkRoot: "/examples/default",
   baseURL: ".",
   diffMethod: "SCHEMA-DIFF",
   loaders: {
@@ -11,5 +11,11 @@ module.exports = {
       options: { method: "POST" },
     },
   },
+  docOptions: {
+    frontMatter: {
+      pagination_next: null,
+      pagination_prev: null,
+    },
+  },
   metatags: [{ name: "googlebot", content: "noindex" }, { charset: "utf-8" }],
 };
diff --git a/packages/docusaurus/tests/__data__/groups.md b/packages/docusaurus/tests/__data__/groups.md
index 3935ea66..9b255374 100644
--- a/packages/docusaurus/tests/__data__/groups.md
+++ b/packages/docusaurus/tests/__data__/groups.md
@@ -29,7 +29,7 @@ This is an example of documentation grouping with GraphQL directive using the `g
     fallback: "Common"
   },
   docOptions: {
-    index: true
+    index: true,
   },
   printTypeOptions: {
     parentTypePrefix: false,
@@ -77,7 +77,7 @@ This is an example of documentation grouping with GraphQL directive using the `g
         fallback: "Common"
       },
       docOptions: {
-        index: true
+        index: true,
       },
       printTypeOptions: {
         parentTypePrefix: false,
diff --git a/packages/printer-legacy/tests/unit/printer.test.ts b/packages/printer-legacy/tests/unit/printer.test.ts
index 1d11d09c..e38f57a4 100644
--- a/packages/printer-legacy/tests/unit/printer.test.ts
+++ b/packages/printer-legacy/tests/unit/printer.test.ts
@@ -170,11 +170,8 @@ describe("Printer", () => {
           "collapsible": undefined,
           "customDirectives": undefined,
           "deprecated": "default",
+          "frontMatter": {},
           "groups": undefined,
-          "header": {
-            "pagination": true,
-            "toc": true,
-          },
           "level": undefined,
           "metatags": [],
           "onlyDocDirectives": [],
@@ -227,11 +224,8 @@ describe("Printer", () => {
           "collapsible": undefined,
           "customDirectives": undefined,
           "deprecated": "default",
+          "frontMatter": {},
           "groups": {},
-          "header": {
-            "pagination": true,
-            "toc": true,
-          },
           "level": undefined,
           "metatags": [],
           "onlyDocDirectives": [],
@@ -292,33 +286,11 @@ describe("Printer", () => {
             "---
             id: an-object-type-name
             title: An Object Type Name
-            hide_table_of_contents: false
-            ---"
-          `);
-    });
-
-    test("returns a Docusaurus document header with ToC disabled", () => {
-      expect.hasAssertions();
-
-      const header = Printer.printHeader(
-        "an-object-type-name",
-        "An Object Type Name",
-        {
-          ...DEFAULT_OPTIONS,
-          header: { ...DEFAULT_OPTIONS.header, toc: false },
-        },
-      );
-
-      expect(header).toMatchInlineSnapshot(`
-            "---
-            id: an-object-type-name
-            title: An Object Type Name
-            hide_table_of_contents: true
             ---"
           `);
     });
 
-    test("returns a Docusaurus document header with pagination disabled", () => {
+    test("returns a Docusaurus document header with custom frontmatter", () => {
       expect.hasAssertions();
 
       const header = Printer.printHeader(
@@ -326,7 +298,7 @@ describe("Printer", () => {
         "An Object Type Name",
         {
           ...DEFAULT_OPTIONS,
-          header: { ...DEFAULT_OPTIONS.header, pagination: false },
+          frontMatter: { draft: true, hide_table_of_contents: null },
         },
       );
 
@@ -334,9 +306,8 @@ describe("Printer", () => {
             "---
             id: an-object-type-name
             title: An Object Type Name
-            hide_table_of_contents: false
-            pagination_next: null
-            pagination_prev: null
+            draft: true
+            hide_table_of_contents: null
             ---"
           `);
     });