3

Can't find this exact question answered. I want to have a data.JSON file in my /public folder which contains a static file which once site is built I can quickly modify without having to rebuild the site. However I'm struggling on how to get this into react. I've tried following instructions from the README, but it's a bit unclear.

If I try:

    class Home extends Component {
      render() {
        const data = require(`${process.env.PUBLIC_URL}/data.json`);

I get the message on compile:

./src/Home.js
    Module not found: You attempted to import /data.json which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.

What's the proper way to include it? I also tried a hacky way by trying to write it to window.DATA in public/index.html but because I believe it has to call Asynchronous (otherwise chrome gives me an error) sometimes the data will be there, sometimes not, and React doesn't seem to like it. Code I tried:

var request = new XMLHttpRequest();
request.open("GET", "%PUBLIC_URL%/data.json", true);
request.send(null);
request.onreadystatechange = function() {
  if ( request.readyState === 4 && request.status === 200 ) {
    window.DATA = JSON.parse(request.responseText);
  }
}

Any help would be appreciated!

5
  • 1
    Did you try using an absolute path as the error message suggested? Commented Sep 8, 2017 at 23:25
  • Like import data from './data.json? How to add the public URL prepend to that? Or something else? In the readme it seems it can be done. Commented Sep 8, 2017 at 23:38
  • I believe if your data.json file is outside the src directory you'll have to use an absolute path, or put your data.json file within the /src/ directory of your project if you want to use a relative path. Commented Sep 8, 2017 at 23:43
  • @reubenb87 were you able to find a different way to call your .json from your public folder besides using the answer below? I'm also looking for away to just require it in. Commented Nov 5, 2017 at 0:02
  • Sorry @DavidTrinh I got it working via the accepted response below, once it was working just focused on other items! Commented Nov 6, 2017 at 3:07

3 Answers 3

3

Borrow the "window" variable.

For example, in file "/public/config.js":

window.samleAppConfig = {
  entryUrl: "service.com/api"
}

Then in file "/src/App.js":

constructor(props) {
  super(props);
  console.log('entryUrl', window.samleAppConfig. entryUrl);
}

And in "/public/index.html":

<div id="root"></div>
<script type="text/javascript" src="config.js"></script>
Sign up to request clarification or add additional context in comments.

Comments

2

Your first solution will not work if you want to put file in public folder as React should not give access to something outside the source folder. Otherwise you can imagine a bad code could allow people access folder c:\windows

Your second solution could be the way to go, but just need a little bit work on the callback. If you start your project with create-react-app, you can put index.js as

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

var xhttp = new XMLHttpRequest();
var data = {};
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
       // Typical action to be performed when the document is ready:
       data = JSON.parse(xhttp.responseText);
       ReactDOM.render(<App appData={JSON.stringify(data)}/>, document.getElementById('root'));
    }
};

xhttp.open("GET", `${process.env.PUBLIC_URL}/data.json`, true);
xhttp.send();

And then your App.js as

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
          <h2>{JSON.parse(this.props.appData).Name}</h2>
      </div>
    );
  }
}

export default App;

I put data.json in the public folder, and I have the object like this:

{
  "Name": "My App"
}

I tried it just now and it can show My App in the page all the time

Comments

-2

You can simply do it like this:

mydata.js

export default {
  myStuff: [ "one","two","three"]
}

In your code

import myData from './mydata.js'

You now have your data in a variable called myData

1 Comment

This doesn't import the the from the public folder as requested by the OP

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.