gatsby-node.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. const path = require(`path`);
  2. const { siteMetadata } = require("./gatsby-config");
  3. const runtime = require("react/jsx-runtime");
  4. const { compileMDX } = require("gatsby-plugin-mdx");
  5. const { renderToStaticMarkup } = require("react-dom/server");
  6. // https://github.com/gatsbyjs/gatsby/issues/28657
  7. exports.onCreateBabelConfig = ({ actions }) => {
  8. actions.setBabelPreset({
  9. name: "babel-preset-gatsby",
  10. options: {
  11. reactRuntime: "automatic",
  12. },
  13. });
  14. };
  15. exports.onCreateNode = async ({ node, actions, getNode, reporter, cache }) => {
  16. const { createNodeField } = actions;
  17. if (node.internal.type !== `Mdx`) return;
  18. const filePath = node.internal.contentFilePath;
  19. let pageType = "unknown";
  20. if (filePath.startsWith(path.resolve("content/guides"))) {
  21. pageType = "guides";
  22. } else if (filePath.startsWith(path.resolve("content/docs"))) {
  23. pageType = "docs";
  24. } else if (filePath.startsWith(path.resolve("content/blog"))) {
  25. pageType = "blog";
  26. } else if (filePath.startsWith(path.resolve("content/playground"))) {
  27. pageType = "playground";
  28. } else if (filePath.startsWith(path.resolve("content/standalone"))) {
  29. pageType = "standalone";
  30. }
  31. const relativePath = path.relative(path.resolve("content"), filePath);
  32. const extension = path.extname(filePath);
  33. const slug = relativePath.replace(extension, "");
  34. createNodeField({
  35. node,
  36. name: `githubPath`,
  37. value: path.join(siteMetadata.github, relativePath),
  38. });
  39. createNodeField({
  40. node,
  41. name: `pageType`,
  42. value: pageType,
  43. });
  44. createNodeField({
  45. node,
  46. name: `slug`,
  47. value: slug,
  48. });
  49. createNodeField({
  50. node,
  51. name: `permalink`,
  52. value: node.frontmatter.external || `/${slug}/`,
  53. });
  54. const fileNode = getNode(node.parent);
  55. if (fileNode && pageType === "blog") {
  56. const result = await compileMDX(
  57. {
  58. source: node.body.split("{/* more */}")[0],
  59. path: node.internal.contentFilePath,
  60. },
  61. {
  62. // These options are requried to allow rendering to string
  63. outputFormat: `function-body`,
  64. useDynamicImport: true,
  65. // Add any custom options or plugins here
  66. },
  67. cache,
  68. reporter
  69. );
  70. if (result && result.processedMDX) {
  71. const { run } = await import("@mdx-js/mdx");
  72. const args = {
  73. ...runtime,
  74. };
  75. const { default: Content } = await run(result.processedMDX, args);
  76. const value = renderToStaticMarkup(Content(args));
  77. createNodeField({
  78. node,
  79. name: `excerpt`,
  80. value,
  81. });
  82. }
  83. }
  84. };
  85. exports.createPages = ({ graphql, actions }) => {
  86. const { createPage } = actions;
  87. const docTemplate = path.resolve(`src/templates/doc.jsx`);
  88. const templates = {
  89. blog: path.resolve(`src/templates/post.jsx`),
  90. standalone: path.resolve(`src/templates/standalone.jsx`),
  91. guides: docTemplate,
  92. docs: docTemplate,
  93. };
  94. return graphql(
  95. `
  96. query loadPagesQuery($limit: Int!) {
  97. allMdx(limit: $limit) {
  98. edges {
  99. node {
  100. id
  101. fields {
  102. pageType
  103. slug
  104. }
  105. frontmatter {
  106. title
  107. external
  108. }
  109. internal {
  110. contentFilePath
  111. }
  112. }
  113. }
  114. }
  115. }
  116. `,
  117. { limit: 1000 }
  118. ).then((result) => {
  119. if (result.errors) {
  120. throw result.errors;
  121. }
  122. result.data.allMdx.edges.forEach(({ node }) => {
  123. const filePath = node.internal.contentFilePath;
  124. const { pageType, slug } = node.fields;
  125. const template = templates[pageType];
  126. if (template && !node.frontmatter.external) {
  127. createPage({
  128. path: `${slug}`,
  129. component: `${template}?__contentFilePath=${filePath}`,
  130. context: { id: node.id },
  131. });
  132. }
  133. });
  134. });
  135. };