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

error Cannot query field "siteSearchIndex" on type "Query" graphql/template-strings

Open TJBriggs opened this issue 5 years ago • 5 comments

I've searched through all the related issues and tried everything I could find, but I'm still getting the following error when I try to save my header component with the Search component included:

error Cannot query field "siteSearchIndex" on type "Query" graphql/template-strings

I'm fairly new to Gatsby so I may have overlooked something. Any help would be greatly appreciated.

Here are the relevant site files:

package.json:

{
	"name": "gatsby-wordpress-starter",
	"description": "",
	"version": "",
	"author": "",
	"dependencies": {
		"@gatsby-contrib/gatsby-plugin-elasticlunr-search": "^2.3.0",
		"babel-plugin-styled-components": "^1.10.1",
		"elasticlunr": "^0.9.5",
		"gatsby": "^2.11.0",
		"gatsby-cli": "^2.7.9",
		"gatsby-image": "^2.1.4",
		"gatsby-plugin-manifest": "^2.1.1",
		"gatsby-plugin-offline": "^2.1.3",
		"gatsby-plugin-postcss": "^2.0.7",
		"gatsby-plugin-react-helmet": "^3.0.12",
		"gatsby-plugin-sharp": "^2.1.5",
		"gatsby-plugin-styled-components": "^3.1.0",
		"gatsby-source-filesystem": "^2.0.39",
		"gatsby-source-wordpress": "^3.0.64",
		"gatsby-transformer-sharp": "^2.1.21",
		"intersection-observer": "^0.7.0",
		"isomorphic-fetch": "^2.2.1",
		"postcss-extend-rule": "^2.0.0",
		"postcss-import": "^12.0.1",
		"postcss-mixins": "^6.2.1",
		"postcss-nested": "^4.1.2",
		"postcss-preset-env": "^6.6.0",
		"postcss-simple-vars": "^5.0.2",
		"prop-types": "^15.7.2",
		"react": "^16.8.6",
		"react-dom": "^16.8.6",
		"react-helmet": "^5.2.1",
		"simple-crypto-js": "^2.0.2",
		"styled-components": "^4.3.2"
	},
	"devDependencies": {
		"prettier": "^1.18.2",
		"typescript": "^3.5.2"
	},
	"keywords": [
		"gatsby",
		"wordpress",
		"ACF",
		"ACF Pro",
		"Advanced Custom Fields",
		"Flexible Content"
	],
	"license": "MIT",
	"scripts": {
		"build": "gatsby build",
		"develop": "gatsby develop",
		"format": "prettier --write src/**/*.{js,jsx}",
		"start": "npm run develop",
		"serve": "gatsby serve",
		"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\""
	},
	"repository": {
		"type": "git",
		"url": "git+https://github.com/gatsbyjs/gatsby-starter-default.git"
	},
	"bugs": {
		"url": "https://github.com/gatsbyjs/gatsby/issues"
	},
	"homepage": "https://github.com/gatsbyjs/gatsby-starter-default#readme",
	"main": "gatsby-browser.js"
}

gatsby-config.js:

module.exports = {
	siteMetadata: {
		title: `Gatsby - Wordpress`,
	},
	plugins: [
		`gatsby-plugin-react-helmet`,
		{
			resolve: `gatsby-source-filesystem`,
			options: {
				name: `images`,
				path: `${__dirname}/src/images`,
		},
		},
		`gatsby-plugin-styled-components`,
		`gatsby-transformer-sharp`,
		`gatsby-plugin-sharp`,
		{
			resolve: `gatsby-plugin-manifest`,
			options: {
				name: `gatsby-starter-default`,
				short_name: `starter`,
				start_url: `/`,
				background_color: `#663399`,
				theme_color: `#663399`,
				display: `minimal-ui`,
				icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
			},
		},
		{
			resolve: `gatsby-source-wordpress`,
			options: {
				baseUrl: `test-gatsby-admin.pantheonsite.io`,
				protocol: `http`,
				hostingWPCOM: false,
				useACF: true,
				acfOptionPageIds: [],
				verboseOutput: true,
				perPage: 100,
				searchAndReplaceContentUrls: {
					sourceUrl: `test-gatsby-admin.pantheonsite.io`,
					replacementUrl: `test-gatsby-admin.pantheonsite.io`,
				},
				concurrentRequests: 10,
				includedRoutes: [
					"**/categories",
					"**/posts",
					"**/pages",
					"**/media",
					"**/menus",
					"**/tags",
					"**/taxonomies",
					"**/users",
					"**/example-cpt",
					"**/example-tax",
				],
				excludedRoutes: [],
				normalizer: function( { entities } ) {
					return entities
				},
			},
		},
		{
			resolve: `@gatsby-contrib/gatsby-plugin-elasticlunr-search`,
			options: {
				// Fields to index
				fields: [ `title`],
				// How to resolve each field`s value for a supported node type
				resolvers: {
					wordpress__PAGE: {
						title: node => node.title,
						path: node => node.slug,
					},
					wordpress__POST: {
						title: node => node.title,
						path: node => node.slug,
					},
				},
			},
		},
		{
			resolve: `gatsby-plugin-postcss`,
			options: {
				postCssPlugins: [
					require( `postcss-import` ),
					require( `postcss-simple-vars` ),
					require( `postcss-nested` ),
					require( `postcss-mixins` ),
					require( `postcss-extend-rule` ),
					require( `postcss-preset-env` )( {
						stage: 0 ,
						autoprefixer: {
							grid: true
						}
					} ),
				],
			},
		},
		{
			resolve: `gatsby-source-filesystem`,
			options: {
				name: `images`,
				path: `${__dirname}/src/images/`,
				ignore: [`**/\.*`], // ignore files starting with a dot
			},
		},
	],
}

search.js:

import React, { Component } from 'react'
import { Index } from 'elasticlunr'
import { Link } from "gatsby"

// Search component
export default class Search extends Component {
	constructor( props ) {
		super( props )
		this.state = {
			query: ``,
			results: [],
		}
	}

	render() {
		return (
		<div>
			<input type="text" value={ this.state.query } onChange={ this.search } />
			<ul>
				{ this.state.results.map( page => (
					<li key={ page.id }>
						<Link to={ "/" + page.path }>{ page.title }</Link>
						{ ": " + page.tags.join( `,` ) }
					</li>
				) ) }
			</ul>
		</div>
		)
	}
	getOrCreateIndex = () =>
		this.index
			? this.index
			: // Create an elastic lunr index and hydrate with graphql query results
				Index.load( this.props.searchIndex )

	search = evt => {
		const query = evt.target.value
		this.index = this.getOrCreateIndex()
		this.setState( {
		query,
		// Query the index with search string to get an [] of IDs
		results: this.index
			.search( query, {} )
			// Map over each ID and return the full document
			.map( ( { ref } ) => this.index.documentStore.getDoc( ref ) ),
		} )
	}
}

header.js:

import React from 'react'
import { StaticQuery, Link } from 'gatsby'
import Img from 'gatsby-image'
import { graphql } from "gatsby"
import './header-styles.css'

import Navigation from '../navigation/navigation'
import Search from '../search/search'

const Header = ( { siteLogo } ) => (
	<StaticQuery
		query={ graphql`
			query SearchIndexQuery {
				siteSearchIndex {
					index
				}
			}
		` }
		render={ data => (
			<header className='site-header'>
				<a href='#main-content' className='screen-reader-text'>Skip to main content</a>
				<div className='site-header__inner'>
					<div className="site-header__wrap">
						<Link to="/" className='site-header__logo'>
							<Img fluid={ siteLogo } alt='Gatsby Logo' />
						</Link>
						<Navigation navType='header-nav' />
					</div>
					<Search searchIndex={ data.siteSearchIndex.index } />
				</div>
			</header>
		) }
	/>
)

export default Header

When following the examples on Github I didn't see any code changes to gatsby-node.js. Was I supposed to update this file to make the search work? Here is my current gatsby-node.js file just in case this may be causing issues:

/**
 * Implement Gatsby's Node APIs in this file.
 *
 * See: https://www.gatsbyjs.org/docs/node-apis/
 */

const path = require(`path`)

exports.createPages = ( { graphql, actions } ) => {
	const { createPage } = actions
	const pageTemplate = path.resolve( './src/templates/page.js' )
	const postTemplate = path.resolve( './src/templates/post.js' )
	const cptTemplate = path.resolve( './src/templates/cpt.js' )
	const pagePassword = path.resolve( './src/templates/page-password.js' )

	return graphql(`
		{
			allWordpressPage {
				edges {
					node {
						id
						slug
						wordpress_id
						path
						template
					}
				}
			}
			allWordpressPost {
				edges {
					node {
						id
						slug
						wordpress_id
						path
						template
					}
				}
			}
			allWordpressWpExampleCpt {
				edges {
					node {
						id
						slug
						wordpress_id
						path
						template
					}
				}
			}
		}
	`).then( result => {
		if ( result.errors ) {
			throw result.errors
		}

		const pages = result.data.allWordpressPage.edges

		pages.forEach( page => {
			const template = page.node.template
			if( 'page-password.php' !== template ) {
				createPage( {
					path: `${ page.node.path }`,
					component: pageTemplate,
					context: {
						id: page.node.wordpress_id,
					},
				} )
			} else {
				createPage( {
					path: `${ page.node.path }`,
					component: pagePassword,
					context: {
						id: page.node.wordpress_id,
					},
				} )
			}
		} )

		const posts = result.data.allWordpressPost.edges
		posts.forEach( post => {
			createPage( {
				path: `/blog/${ post.node.slug }`,
				component: postTemplate,
				context: {
					id: post.node.wordpress_id,
				},
			} )
		} )

		const cptPosts = result.data.allWordpressWpExampleCpt.edges
		cptPosts.forEach( post => {
			createPage( {
				path: `/example-cpt/${ post.node.slug }`,
				component: cptTemplate,
				context: {
					id: post.node.wordpress_id,
				},
			} )
		} )
	} )
}

TJBriggs avatar Jul 11 '19 16:07 TJBriggs

Hey!

I never messed around with gatsby and wordpress. I did some work with strapi though and I came across the same problem as you. Even though the names of the queries are wordpress__PAGE, wordpress__POST, I learnt that node types usual start with a Capital Letter e.g Wordpress__PAGE.

Try to write the type of the node in the Resolvers object and not the name. resolvers: { Wordpress__PAGE: { title: node => node.title, path: node => node.slug, }, Wordpress__POST: { title: node => node.title, path: node => node.slug, }, }, Hope it helps

vabelha avatar Jul 16 '19 15:07 vabelha

@vabelha Thanks for the reply and I really appreciate the help. Unfortunately, I tried updating the spelling of the resolvers, but I'm still getting the same error.

TJBriggs avatar Jul 23 '19 21:07 TJBriggs

@TJBriggs were you able to resolve this issue? I didn't get any error at wordpress__POST while building but got and an error at index

TypeError: Cannot read property 'forEach' of undefined",
        "    at createOrGetIndex

UPDATE I was able to figure this out by using fields array in the gatsby-config.js file

mkamranhamid avatar Jul 06 '20 09:07 mkamranhamid

I had a similar issue on a Gatsby project. I was getting an error that said "cannot query field on template strings." To isolate the problem I ran the same query in the GraphQL IDE and found no error.

Then I saw a thread on Github where someone suggested restarting the server. So I did that and it worked. I forgot every time you make changes to the gatsby-config.js file you have to restart the server for it to take effect. So until I did that it was throwing errors when it went to look for data I was querying that hadn't yet been updated.

Hope that's helpful to folks that run into the same problem!

mike2477 avatar Jun 09 '21 19:06 mike2477

Hello. I had same issue on a Gatsby and Wordpress project.

I restarted the server. It worked. Hope it helps.

yukaaan avatar Jan 07 '22 00:01 yukaaan