I have a file structure that looks like this:
conferences/
en.json
ar.json
meetups/
en.json
ar.json
I want to be able to use either the filesystem source or the JSON transformer plugin to load a specific JSON file. e.g. In a certain case I only want to load conferences/en.json.
I've tried using the GraphQL API but I could never get it to load a specific JSON file no matter how I tried, I could only filter on nodes within the JSON files, but not the files themselves. The filesystem source plugin allowed me to filter to only get the specific files I want, but I wasn't able to get their contents through it. The only approach I was able to get to work is to use the filesystem source plugin with this GraphQL query
{
allFile(filter: {name: {eq: "en"}, relativeDirectory: {eq: "conferences"}}) {
edges {
node {
publicURL
}
}
}
}
and then fetching the JSON and parsing it myself:
let readJSON = (url) => {
console.log(url);
let response = await fetch(url);
let json = await response.json();
return json;
}
const ConferencesPage = ({data}) => (
<Layout>
<ul>
{data.allFile.edges.map((elem) =>
<li>
{console.log(elem)}
<Conference conference={readJSON(elem.node.publicURL)} key={i} />
</li>
)}
</ul>
<h1>Hi from conferences</h1>
<p>Welcome to page 2</p>
<Link to="/">Go back to the homepage</Link>
</Layout>
)
Am I thinking about this the wrong way? Is there perhaps another plugin that can read file contents that I can utilize instead of all the solutions I tried?
Hey @obahareth,
I've played around with this and the best approach I found was using both plugins and the allFile query. Here's how I got it working:
I recreated your directory structure:
conferences/
en.json
ar.json
meetups/
en.json
ar.json
Adding a simple json object to each file:
{
"name": "Omar"
}
I installed both plugins:
npm install --save gatsby-transformer-json gatsby-source-filesystem
and updated the plugin settings in gatsby-config.js:
module.exports = {
siteMetadata: {
title: 'Gatsby Default Starter',
},
plugins: [
'gatsby-plugin-react-helmet',
{
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.
},
},
`gatsby-transformer-json`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `meetups`,
path: `${__dirname}/src/meetups`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `conferences`,
path: `${__dirname}/src/conferences`,
}
},
'gatsby-plugin-offline'
]
}
I then filtered the allFile query and requested the return of childConferenceJson, which will be contents of ./src/conferences/en.json:
{
allFile (filter: {
name: { eq : "en" }
sourceInstanceName: { eq : "conferences" }
}) {
edges {
node {
childConferencesJson {
name
}
}
}
}
}
This returns me:
{
"data": {
"allFile": {
"edges": [
{
"node": {
"childConferencesJson": {
"name": "Omar"
}
}
}
]
}
}
}
I hope that helps!
If you run into any problems, try deleting your .cache directory before running gatsby develop.
That's a huge help and it worked out great for me, thanks so much @dakebl!
Most helpful comment
Hey @obahareth,
I've played around with this and the best approach I found was using both plugins and the
allFilequery. Here's how I got it working:I recreated your directory structure:
Adding a simple json object to each file:
I installed both plugins:
and updated the plugin settings in
gatsby-config.js:I then filtered the
allFilequery and requested the return ofchildConferenceJson, which will be contents of./src/conferences/en.json:This returns me:
I hope that helps!
If you run into any problems, try deleting your
.cachedirectory before runninggatsby develop.