Every time I search about this I get something related to react router and lazy loading. Isn't there a way to create an entirely separate page independent of index.js?
I created admin.js within my react project. If I go to http://localhost:3000/admin, it still loads index.js. I quite do not understand this bit of react if it is possible.
No, this is not possible without router. And here is why: your index.js has nothing to do with what is loaded in the browser.
When navigating to http://localhost:3000 your dev server actually serves a index.html to your browser. In it is a reference to a bundle.js (or however you name it) containing a bundled version of your .js files. So, http://localhost:3000/admin references to a admin.html which does of course not exist (unless you create it). But, doing this has several disadvantages over react-router. Because at build (or bundle) time index.js and admin.js will be two separate apps. Two separate bundle.js. Twice the amount of work needed to package it. Twice the amount of (maybe generated) .html files. Means no shared data at all. Twice the loading time in your browser. And many more.
I'd opt for react-router ;)
Edit: Of course it is not exactly twice in the points mentioned above. I am aware of that. But you get my point.
Related
The app
The application was made using ReactJS, React Router Dom, Styled Components and Redux ducks.
The backend we consume is also made by us using Amazon Amplify and GraphQL.
The goal
We need to define the meta tags of one of the application pages so that it is possible to share personalized links to users
in social networks using OpenGraphic meta tags and the like.
The problem
The project was made in ReactJS and ReactJS has only one HTML page as root (/public/index.html), in this way, everything is generated with Javascript in a root tag, and when it arrives in the browser it is transpiled, as we already know. The problem is that the crawlers responsible for understanding the meta tags are not able to understand Javascript and end up not finding the dynamic data that I am defining on the page that I need to share the link on. They understand that there is one html file and only.
Attempts to resolve the issue
1) Define the meta tags in the /public/index.html file itself
This solution doesn't work because the data we are using is dynamic and the index.html file is a static file
2) Using react-helmet
The solution allows meta tags to be defined, but as already mentioned, crawlers don't understand JS. So, despite being on the page, the meta tags do not appear when sharing the link.
3) Using some SSR technology
This is a possible solution, but we were unable to integrate any SSR Framework into React. And it is not feasible to change the base technology of the project. We can't just switch from React to Next, for example, as the project is already complete.
4) Using a small server made with express.js along with the React application to replace the meta tags in index.html with string.replace() simulating something like an SSR
This solution works, but it causes two requests to be made every time the page is accessed, once by express.js and once on the front-end side by React. Due to the number of requests increasing, this solution was discarded. But if necessary, you can do it. In this case it is also necessary to check if Amplify can keep the application and the small server running in the same project.
5) Using react-snap with react-helmet
React-snap allows you to create html snapshots of the pages of a React project based on their routes and links, this added to react-helmet generates a perfect solution for links to be treated well by web crawlers when they are shared. But the solution doesn't work with dynamic routes. For example, /your-route/:id is a dynamic route that expects an id to be fully defined. React-snap gets lost when trying to create a snapshot of a route that only exists when the id is set. Unfortunately, this solution doesn't work.
These were the solutions we used to try to solve the problem, but it was not possible yet. Probably attempt 4 would be the most ideal to solve the problem. But we are looking for the best way that will not generate reworks and future problems. If someone knows a better way to do that, would help us a lot!
So I have a React app with this structure
-MyApp
-public
--images
---Adam.png
---Jane.png
-src
--components
For one of my components I want to show all the images. Is there a way I can get array of the filenames in my public/images folder? I know how to map the array to a list of images but not sure how to get that array of file names in the first place.
This is natural question when doing this (because alternative is always importing those one by one which seems wrong) but react is in the end builded into some optimized static code. So whole issue is "what would happen if you added another image to that folder and refreshed page?". And answer is that it cannot react to it because that loop you are doing (one generating img tags or something else) is ran during build. What you need is server that "reads" those folders and lets you know what is there (to your already built app) and you can update state and that renders more elements during runtime in response to server.
In Webpack there is this other option (as mentioned by #UbeytDemir) that can understand what will be public folder and iterate those contents during build, but that still means you have to rebuild the app after each new image, because it simply cant do this during run time without server. It only unifies those imports into one line but imho it's important to understand why this is impossible to do in client's app.
I am using django on the backend and on the front end I am using react with create-react-app.
I have different apps on my web page that are somewhat independent from each other:
mydomainname/home
mydomainname/foo
mydomainname/bar
They are all somewhat connected but logically completely different which is why I separated them.
Is this handled with only one create-react-app and one index.html file in the build folder? And something like the browser router package for the different apps?
For example, if I look at the Facebook homepage (in case I want to build that with React) I understand that my news feed and my profile page and other people's pages are all connected and share similar components which is why it would make sense to have one index.html file.
But if I create a new public page (e.g. for a business figure), are all these components and functionalities handled in the same one index.html file? I could imagine that this will run into memory leaks and performance issues, or is this not the case? I can't seem to find anything about that neither in the create-react-app documentation nor through google.
React is not Html. In React you have only one page named index.html in folder public. The "pages" in react are named as 'Components', so you just create components and link them to each other. The first generated example component is App (App.js) component in src folder. All the transitions (transition from one component to second) will be done in index.html file.
I'm not really sure how to word this so it's making it hard to search but if I have a big application and each component is in it's own js file, then it doesn't make sense to load ALL component files in index.html. The user might never even see a large number of these components as they are navigating through the app.
So the question would be, how can we load components as they are needed in a view that houses them vs all at once?
In a perfect world, as a page is routed it would know the components on the view and know if it's already registered that component and if not, go get the js file to do so and register it automatically for us before running the view. This would require some kind of configuration that says this string component name is this js file on the server.
Does anything like this exist?
Looks like it's called lazy loading of scripts. There seems to be a really easy angular module for this!
https://oclazyload.readme.io/
Very cool and close to what I was hoping for. Ideally I'd love for config of components and then dynamic loading of components when the view uses then but this is close enough. Perhaps I can enhance this to pre-read the view html looking for components that aren't registered with angular already and then search the config to get them if not.
I found interesting link on how to organize my files and load files using require.js http://backbonetutorials.com/organizing-backbone-using-modules/ , the only issue I have with that example is that they load everything in the beginning even asynchronously. I was wondering if it is possible load .js files only when they needed... For example if I click on Project List ( http://backbonetutorials.com/examples/modular-backbone/#/projects ), it checks on which url we are currently located, and load projects.js and list.js after that....
For small apps it would be ok, but for big apps with big classes it might take a while, before all classes will be loaded to the browser, for all routers.
I think creator of that example answered this question more accurately. Here is his answer: http://backbonetutorials.com/organizing-backbone-using-modules/#IDComment-CommentText210764496 , see the reply
First of all, you would really need a big application in order to need that. The files of a normal application, minified and gzipped, are not a significant load. And then you can use caching to load them only once in each browser.
If you really want to, of course you can do partial loading, in the same way you do it for the application in the example (in the router, the projects route will first ensure the project-related js files are loaded, and only then do the fetching/view initialization etc)