gatsby-plugin-elasticlunr-search icon indicating copy to clipboard operation
gatsby-plugin-elasticlunr-search copied to clipboard

Error: SiteSearchIndex.index field type must be Output Type but got: SiteSearc hIndex_Index.

Open ciokan opened this issue 6 years ago • 7 comments

Any idea why I get this error when I enter your code in gatsby-config file?

ciokan avatar May 12 '18 10:05 ciokan

@ciokan: Hi! Thank you for submitting an issue. Hopefully, we can get it resolved quickly.

Would you mind posting the relevant gatsby-config.js file? Also, what version of the plugin are you using? Finally, did you follow an example to configure the plugin in gatsby-config.js and, if so, which example did you use? There is a demo site using this plugin in another repo that may be of help.

Let me know some of this information and I'll try to reproduce/troubleshoot your problem. Thanks again!

andrew-codes avatar May 12 '18 23:05 andrew-codes

Hi,

Here's my gatsby config:

module.exports = {
	siteMetadata: {
		title: 'Gatsby',
	},
	plugins: [
		'gatsby-plugin-sass',
		'gatsby-plugin-react-helmet',
		{
			resolve: `gatsby-source-filesystem`,
			options: {
				path: `${__dirname}/src/blog/posts`,
				name: "markdown-pages",
			},
		},
		'gatsby-transformer-remark',
		{
			resolve: `gatsby-plugin-google-analytics`,
			options: {
				trackingId: `UA-36099094-18`,
			},
		},
		{
			resolve: `gatsby-transformer-remark`,
			options: {
				plugins: [
					{
						resolve: `gatsby-remark-prismjs`,
						options: {
							// Class prefix for <pre> tags containing syntax highlighting;
							// defaults to 'language-' (eg <pre class="language-js">).
							// If your site loads Prism into the browser at runtime,
							// (eg for use with libraries like react-live),
							// you may use this to prevent Prism from re-processing syntax.
							// This is an uncommon use-case though;
							// If you're unsure, it's best to use the default value.
							classPrefix: "language-",
							// This is used to allow setting a language for inline code
							// (i.e. single backticks) by creating a separator.
							// This separator is a string and will do no white-space
							// stripping.
							// A suggested value for English speakers is the non-ascii
							// character '›'.
							inlineCodeMarker: null,
							// This lets you set up language aliases.  For example,
							// setting this to '{ sh: "bash" }' will let you use
							// the language "sh" which will highlight using the
							// bash highlighter.
							aliases: {},
						},
					},
				],
			},
		},
		{
			resolve: `@andrew-codes/gatsby-plugin-elasticlunr-search`,
			options: {
				// Fields to index
				fields: [
					'title',
				],
				// How to resolve each field's value for a supported node type
				resolvers: {
					// For any node of type MarkdownRemark, list how to resolve the fields' values
					MarkdownRemark: {
						title: node => node.frontmatter.title,
					},
				},
			},
		},
	],
};

package.json:

{
 ...
  "dependencies": {
    "compass-mixins": "^0.12.10",
    "country-iso-2-to-3": "^1.0.1",
    "elasticlunr": "^0.9.5",
    "gatsby": "^1.9.260",
    "gatsby-link": "^1.6.40",
    "gatsby-paginate": "^1.0.14",
    "gatsby-plugin-google-analytics": "^1.0.31",
    "gatsby-plugin-react-helmet": "^2.0.11",
    "gatsby-plugin-sass": "^1.0.25",
    "gatsby-remark-prismjs": "^2.0.2",
    "gatsby-source-filesystem": "^1.5.35",
    "gatsby-transformer-remark": "^1.7.40",
    "jquery": "^3.3.1",
    "lodash": "^4.17.10",
    "prismjs": "^1.14.0",
    "prop-types": "^15.6.1",
    "rc-slider": "^8.6.1",
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "react-helmet": "^5.2.0",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.2.2",
    "react-simple-maps": "^0.12.0",
    "redux": "^4.0.0",
    "redux-saga": "^0.16.0",
    "redux-tooltip": "^0.7.2"
  },
  "scripts": {
    "build": "gatsby build",
    "develop": "gatsby develop",
    "format": "prettier --write 'src/**/*.js'",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "@andrew-codes/gatsby-plugin-elasticlunr-search": "^1.0.4",
    "prettier": "^1.11.1"
  }
}

As an example I only used your github page for this plugin.

Thank you.

ciokan avatar May 13 '18 15:05 ciokan

@ciokan When do you see this error? Is it during runtime or while building the site? I am going to try to set up a demo using your gatsby config and versions in your package.json to try to troubleshoot. I'll let you know what I find.

andrew-codes avatar May 20 '18 23:05 andrew-codes

I also noticed you have gatsby-transformer-remark registered twice. I am not sure if this will cause problems with the search plugin, but it probably is worth removing in either case.

andrew-codes avatar May 20 '18 23:05 andrew-codes

I have a couple of additional questions. How are you converting markdown files into actual pages (typically in a gatsby-node.js file. Also, what does the consuming search component code look like? The plugin provides a way to retrieve a search index via GraphQL, but does not implement a search component to leverage it. This is primarily up to you to decide how you want the search interactions to work on your site. Would you mind posting what the search component(s) look like?

  • Thanks

andrew-codes avatar May 20 '18 23:05 andrew-codes

I have the same problem at build time. My error is slightly different, but I think it's the same issue. I've included the error message and relevant files below. Any help would be appreciated @andrew-codes!

Error: SiteSearchIndex.index provided incorrect OutputType: '"SiteSearchIndex_  Index"

package.json

{
  "name": "@dvtl/website",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "apollo:client:codegen": "apollo client:codegen --outputFlat --customScalarsPrefix=GraphQL_ '--queries={{src,node_modules/gatsby-transformer-sharp}/**/*,*.tsx}' --target=typescript --tagName graphql src/types/graphql.tsx",
    "build": "tsc --build",
    "deploy:redirects": "ts-node ./bin/deployRedirects.ts",
    "gatsby:build": "node --optimize_for_size -r ts-node/register ./node_modules/.bin/gatsby build",
    "gatsby:serve": "./node_modules/.bin/gatsby serve",
    "generate:svgs": "svg-to-react src",
    "generate:zapier": "ts-node ./bin/fetch-zapier-templates.ts",
    "start": "tsc --build && concurrently -n gatsby,tsc -c green,blue \"ts-node -r tsconfig-paths -P tsconfig.json ./node_modules/.bin/gatsby develop -H 0.0.0.0 -p 8000\" \"tsc -b -w --preserveWatchOutput\"",
    "lint": "tsc --build && tslint -p tsconfig.lint.json"
  },
  "jest": {
    "globals": {
      "ts-jest": {
        "tsConfig": "tsconfig.json"
      },
      "NODE_ENV": "test"
    },
    "moduleFileExtensions": [
      "js",
      "ts",
      "tsx",
      "json"
    ],
    "moduleNameMapper": {
      ".*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/.jest/imageMock.tsx",
      "@dvtl/website/(.*)": "<rootDir>/src/$1"
    },
    "modulePaths": [
      "<rootDir>/src"
    ],
    "testRegex": "\\.spec\\.tsx?$",
    "testURL": "http://localhost/",
    "transform": {
      "\\.tsx?$": "ts-jest"
    }
  },
  "dependencies": {
    "@babel/core": "^7.2.2",
    "@gatsby-contrib/gatsby-plugin-elasticlunr-search": "^2.2.1",
    "@types/date-fns": "^2.6.0",
    "@types/jest": "^23.3.11",
    "@types/lodash": "^4.14.123",
    "@types/node": "^10.0.0",
    "@types/node-fetch": "^1.6.9",
    "@types/react": "^16.8.2",
    "@types/react-dom": "^16.8.0",
    "@types/react-helmet": "^5.0.5",
    "@types/react-transition-group": "^2.0.15",
    "awesome-typescript-loader": "^5.2.1",
    "babel-core": "6.26.3",
    "date-fns": "^1.30.1",
    "gatsby": "^2.3.3",
    "gatsby-image": "^2.0.5",
    "gatsby-plugin-canonical-urls": "^2.0.5",
    "gatsby-plugin-google-tagmanager": "^2.0.5",
    "gatsby-plugin-react-helmet": "^3.0.0",
    "gatsby-plugin-remove-trailing-slashes": "^2.0.6",
    "gatsby-plugin-robots-txt": "^1.3.0",
    "gatsby-plugin-sentry": "^1.0.1",
    "gatsby-plugin-sharp": "^2.0.32",
    "gatsby-plugin-sitemap": "^2.0.1",
    "gatsby-plugin-typescript": "^2.0.3",
    "gatsby-remark-autolink-headers": "^2.0.10",
    "gatsby-remark-copy-linked-files": "^2.0.8",
    "gatsby-remark-embed-gist": "^1.1.7",
    "gatsby-remark-images": "^2.0.1",
    "gatsby-source-filesystem": "^2.0.1",
    "gatsby-transformer-json": "^2.1.6",
    "gatsby-transformer-remark": "^2.2.5",
    "gatsby-transformer-sharp": "^2.1.17",
    "graphql": "0.13.2",
    "jest": "^23.6.0",
    "jest-cli": "^23.6.0",
    "lodash": "^4.17.11",
    "node-fetch": "^2.1.2",
    "prettier": "^1.11.1",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-helmet": "^5.2.0",
    "react-transition-group": "^2.5.2",
    "strip-markdown": "^3.0.3",
    "ts-jest": "^23.10.5",
    "ts-node": "^7.0.1",
    "tslib": "^1.9.0",
    "typeface-source-serif-pro": "^0.0.73",
    "typescript": "^3.4.1"
  },
  "devDependencies": {
    "@types/react-test-renderer": "^16.0.3",
    "@types/yargs": "^12.0.5",
    "apollo": "^2.6.1",
    "gatsby-remark-smartypants": "^2.0.9",
    "react-test-renderer": "^16.8.6",
    "require-env": "^0.2.1",
    "tagged-template-noop": "^2.1.0",
    "tsconfig-paths": "^3.7.0",
    "yargs": "^12.0.5"
  },
  "apollo": {
    "client": {
      "service": {
        "endpoint": {
          "url": "http://localhost:8000/___graphql"
        }
      }
    }
  }
}

gatsby-config.tsx

const { GATSBY_BASE_URL = "https://dovetailapp.com", SENTRY_DSN = "" } = process.env;

export const siteMetadata = {
  siteName: "Dovetail",
  siteUrl: GATSBY_BASE_URL,
};

export const plugins = [
  "gatsby-plugin-react-helmet",
  "gatsby-plugin-remove-trailing-slashes",
  "gatsby-plugin-sitemap",
  "gatsby-plugin-typescript",
  "gatsby-plugin-typestyle",
  "gatsby-transformer-sharp",
  "gatsby-transformer-json",
  {
    resolve: `@gatsby-contrib/gatsby-plugin-elasticlunr-search`,
    options: {
      fields: ["authors", "title", "path"],
      resolvers: {
        MarkdownRemark: {
          authors: (node: { frontmatter: { authors: string[] | null } }) => node.frontmatter.authors,
          title: (node: { frontmatter: { title: string | null } }) => node.frontmatter.title,
          path: (node: { fields: { path: string | null } }) => node.fields.path,
        },
      },
    },
  },
  {
    resolve: "gatsby-plugin-sharp",
    options: {
      defaultQuality: 80,
      stripMetadata: true,
    },
  },
  {
    resolve: "gatsby-source-filesystem",
    options: {
      path: "./src/pages/blog",
      name: "blog",
    },
  },
  {
    resolve: "gatsby-source-filesystem",
    options: {
      path: "./src/pages/company/careers",
      name: "careers",
    },
  },
  {
    resolve: "gatsby-source-filesystem",
    options: {
      path: "./src/pages/customers",
      name: "customers",
    },
  },
  {
    resolve: "gatsby-source-filesystem",
    options: {
      path: "./src/data",
      name: "data",
    },
  },
  {
    resolve: "gatsby-source-filesystem",
    options: {
      path: "./src/pages/help",
      name: "help",
    },
  },
  {
    resolve: "gatsby-source-filesystem",
    options: {
      path: "./src/pages/legal",
      name: "legal",
    },
  },
  {
    resolve: "gatsby-source-filesystem",
    options: {
      ignore: ["**/*.tsx", "**/*.md", "**/*.ts", "**/*.svg", "**/*.gif"],
      path: "./src/pages",
      name: "images",
    },
  },
  {
    resolve: "gatsby-transformer-remark",
    options: {
      plugins: [
        {
          resolve: "gatsby-remark-smartypants",
          options: {
            backticks: false,
          },
        },
        "gatsby-remark-copy-linked-files",
        {
          resolve: "gatsby-remark-embed-gist",
          options: {
            includeDefaultCss: false,
          },
        },
        {
          resolve: "gatsby-remark-images",
          options: {
            backgroundColor: "transparent",
            linkImagesToOriginal: true,
            maxWidth: 800,
            quality: 80,
            withWebp: true,
          },
        },
        {
          resolve: "gatsby-remark-autolink-headers",
          options: {
            offsetY: 64,
            icon: false,
          },
        },
      ],
    },
  },
  {
    resolve: "gatsby-plugin-google-tagmanager",
    options: {
      id: "GTM-M2PTNW9",
      includeInDevelopment: false,
    },
  },
  {
    resolve: "gatsby-plugin-sentry",
    options: {
      dsn: SENTRY_DSN,
      config: {
        environment: process.env.SENTRY_ENVIRONMENT,
        release: process.env.SENTRY_RELEASE,
        version: "3.24.2",
      },
    },
  },
  {
    resolve: "gatsby-plugin-canonical-urls",
    options: {
      siteUrl: "https://dovetailapp.com",
    },
  },
  {
    resolve: "gatsby-plugin-robots-txt",
    options:
      process.env.PREVENT_CRAWLING === "true"
        ? {
            policy: [{ userAgent: "*", disallow: ["/"] }],
            sitemap: null,
            host: null,
          }
        : { policy: [{ userAgent: "*", disallow: ["/confirm", "/404", "/504", "/users/*"] }] },
  },
];

gatsby-node.tsx

import { TsConfigPathsPlugin } from "awesome-typescript-loader";
import * as path from "path";
import { GatsbyCreatePages, OnCreateNode, OnCreateWebpackConfig } from "./src/types/gatsby";
import { createBlogPosts } from "./src/util/createBlogPosts";
import { createCaseStudies } from "./src/util/createCaseStudies";
import { createHelpArticles } from "./src/util/createHelpArticles";
import { createIntegrationPages } from "./src/util/createIntegrationPages";
import { createJobPosts } from "./src/util/createJobPosts";
import { createLegalDocuments } from "./src/util/createLegalDocuments";

export const onCreateWebpackConfig: OnCreateWebpackConfig = ({ actions }) => {
  actions.setWebpackConfig({
    resolve: {
      plugins: [new TsConfigPathsPlugin({ configFileName: "tsconfig.json" })],
    },
  });
};

export const onCreateNode: OnCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions;

  if (node.internal.type === "MarkdownRemark") {
    // Get the parent node
    const parentNode = getNode(node.parent);

    // Create a field on this node for the "collection" of the parent
    // NOTE: This is necessary so we can filter `allMarkdownRemark` by
    // `collection` otherwise there is no way to filter for only markdown
    // documents of type `post`.
    // tslint:disable-next-line
    if (typeof parentNode.sourceInstanceName === "string") {
      createNodeField({
        node,
        name: "collection",
        value: parentNode.sourceInstanceName,
      });
    }

    if (node.fileAbsolutePath.match(/\/src\/pages\/blog\//) !== null) {
      const blogPath = path.join(__dirname, "src", "pages", "blog");
      const value = "/" + path.normalize(path.relative(path.dirname(blogPath), path.dirname(node.fileAbsolutePath)));
      createNodeField({ node, name: "path", value });
    }

    if (node.fileAbsolutePath.match(/\/src\/pages\/customers\//) !== null) {
      const customersPath = path.join(__dirname, "src", "pages", "customers");
      const value = "/" + path.normalize(path.relative(path.dirname(customersPath), path.dirname(node.fileAbsolutePath)));
      createNodeField({ node, name: "path", value });
    }

    if (node.fileAbsolutePath.match(/\/src\/pages\/company\/careers\//) !== null) {
      const postPath = path.join(__dirname, "src", "pages", "company", "careers");
      const value =
        "/" + path.normalize(path.relative(path.dirname(path.dirname(postPath)), path.dirname(node.fileAbsolutePath)));
      createNodeField({ node, name: "path", value });
    }

    if (node.fileAbsolutePath.match(/\/src\/pages\/help\//) !== null) {
      const helpPath = path.join(__dirname, "src", "pages", "help");
      const value = "/" + path.normalize(path.relative(path.dirname(helpPath), path.dirname(node.fileAbsolutePath)));
      createNodeField({ node, name: "path", value });
    }

    if (node.fileAbsolutePath.match(/\/src\/pages\/legal\//) !== null) {
      const legalPath = path.join(__dirname, "src", "pages", "legal");
      const value = "/" + path.normalize(path.relative(path.dirname(legalPath), path.dirname(node.fileAbsolutePath)));
      createNodeField({ node, name: "path", value });
    }
  }
};

export const createPages: GatsbyCreatePages = async api => {
  await createBlogPosts(api);
  await createCaseStudies(api);
  await createHelpArticles(api);
  await createIntegrationPages(api);
  await createJobPosts(api);
  await createLegalDocuments(api);
};

Search component

import { LocationLink } from "@dvtl/ui-components";
import { Index } from "elasticlunr";
import { graphql, useStaticQuery } from "gatsby";
import React, { useMemo, useState } from "react";

interface SearchResult {
  authors: string[] | null;
  id: string;
  title: string | null;
  path: string | null;
}

// Search component
export const SearchInput: React.FC = () => {
  const [query, setQuery] = useState<string>("");
  const [results, setResults] = useState<ReadonlyArray<SearchResult>>([]);

  const data = useStaticQuery(graphql`
    query SearchIndexQuery {
      siteSearchIndex {
        index
      }
    }
  `);

  const index = useMemo(() => Index.load(data), [data]);

  return (
    <div>
      <input
        type="text"
        value={query}
        onChange={e => {
          const query = e.target.value;
          setQuery(query);
          // tslint:disable-next-line:no-any
          setResults(index.search(query, {}).map(({ ref }: { ref: any }) => index.documentStore.getDoc(ref)));
        }}
      />
      <ul>
        {results.map(page => (
          <li key={page.id}>
            {page.path !== null ? (
              <LocationLink location={{ internal: true, path: page.path }}>{page.title}</LocationLink>
            ) : (
              page.title
            )}
          </li>
        ))}
      </ul>
    </div>
  );
};

humphreybc avatar May 21 '19 06:05 humphreybc

I had the same issue, likely due to the use of V2 for Gatsby, the fork @gatsby-contrib/gatsby-plugin-elasticlunr-search solved my issue.

ldeny avatar May 30 '19 18:05 ldeny