Loading Django static files from React component - reactjs

I am fairly new to React/Django/web development in general. I know there are a lot of questions on SO about how to load static files in Django templates, but I couldn't find anything helpful on how to do this in React components.
Scenario: I am building a React-Django app, and one of the features is to render a PDF document based on some user input. I am able to render the pdf successfully with react-pdf if the file is stored somewhere in the react app's source tree.
However, I want to serve these pdf files from the backend. Currently, I have a Django model with a FilePathField that points to where these pdfs are on my filesystem. What is the best practice for using this file path to render the pdf in React? Also, is this approach even correct?

I made it work under development settings. Here are the steps that I followed
First, in the project-level urls.py, add staticfiles_urlpatterns to urlpatterns
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
path('admin/', admin.site.urls),
path('ml/', include('ml.urls'))
]
urlpatterns += staticfiles_urlpatterns()
Second, specify where your static files are in settings.py. In my case, I put all of these files in the project-level assets folder.
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'assets')
Finally, I just send the static URL as a response (e.g /static/assets/sample.pdf) to a react component that can render pdfs.
Would welcome any feedback in the comments. Thanks!

Related

URL config Wagtail-pages in own Django project

I have set up my own Django-project. I have no own app’s installed. That’s for later. What I did was copying the ‘base’ and ‘blog’ app from the bakerydemo to my own project. These run fine, I can access the blog-pages and the admin-site from wagtail.
Only problem is the root url is now a blank-page (can’t add wagtail-field or anything). My wagtail homepage is now on ip-adress/home and it should be on ip-adress. This is my url-config:
from wagtail.admin import urls as wagtailadmin_urls
from wagtail import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('cms/', include(wagtailadmin_urls)),
path('documents/', include(wagtaildocs_urls)),
# path('pages/', include(wagtail_urls)),
path('', include(wagtail_urls)),
# path("test404/", TemplateView.as_view(template_name="404.html")>
# path("test500/", TemplateView.as_view(template_name="500.html")>
]
How can I change this? So my first wagtail page is on root-url and not on root-url/home/
Thnx in advanced.
Edit: found this on the wagtail docs, but don’t know how to apply:
Note that there’s one small difference when not using the Wagtail project template: Wagtail creates an initial homepage of the basic type Page, which does not include any content fields beyond the title. You’ll probably want to replace this with your own HomePage class - when you do so, ensure that you set up a site record (under Settings / Sites in the Wagtail admin) to point to the new homepage.
Instead of trying to move your wagtail page to root-url, you should create (or update) the default site so its root_page should be the page currently shown at /home/

How to provide data to react with drf without extra requests?

I build a single page application with react and django rest framework. I want to have an ability to change "static" info through django admin interface to avoid unnecessary extra deploy every time. Such info like background image and text from about section.
To edit it I create cms django app and register models in admin.
To serve frontend in production I use TemplateView from django.views.generic package. It serves html file from bundled react app directory. here's part of root urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
# ...
# api endpoints here
# ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += [re_path(r'^.*', TemplateView.as_view(template_name='index.html'))]
to serve it in development I use react-scripts start from create-react-app
How can I pass information like the current url of the background image, text for about section, etc. there?
Simple option is to create bunch of views to get this info and request all the data from react app, but I don't really like this approach.
another option is to redefine TemplateView like this
from django.views import generic
class TemplateView(generic.TemplateView):
template_name = 'index.html'
def get_context_data(self, **kwargs):
context_data = dict()
# get all data from db here
return context_data
But how then I use this in react app? in production and in development.
I believe there should be correct way to solve such problem.
One possible solution I found is to hardcode url to background image on frontend and create or update symlink corresponding to this url.
So when I upload new image on django admin, behind scene it saves record in the database, save file itself and update symlink. In this way I also able to set another image as active just updating symlink in process of saving.
This solution looks good for me, but only works for static files, not text data.

React i18next loading translation files both from frontend (e.g. localhost :3000) and backend (e.g. localhost:5000)

I am making one react app which fetches data from backend and displays in the browser. For changing the language for static names (like in header, footer), it is changed if I set locales folder inside public folder, and creating all the json files for required language code.
Now, I want to load the translation files from the backend as well, because, the data fetched from the backend is always random, and backend will send the corresponding translation files.
I am so much of confused of how to achieve that.
I have been through lots of stackoverflow solutions, which suggest to use custom backend plugin. But, I am confused how to create the custom backend plugin.
here is the part of code of my i18next.js configuration :
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
i18n
.use(initReactI18next)
.use(Backend)
.init({
ns:['common', 'translation'],
defaultNS : 'common',
//still loads the translation files if I do not define below line (because it is in public folder in react app)
backend: { loadPath: "/locales/{{lng}}/{{ns}}.json" }
});
From the above code, I am just able to load the translation files that is in the frontend.
If I change the line "backend" as :
backend : { loadPath : "http://localhost:5000/locales/{{lng}}/{{ns}}.json"
It will load the translation files from backend server at localhost: 5000. But, the translation files located in the public folder in not loaded now.
Can anyone help with some example, how to load both paths so that the translation files from both frontend and backend works.
When you have both defined resources in your local project and backend translations, you're capable of using i18next-chained-backend library to support both. Refer the short example here.
Reference: https://www.i18next.com/how-to/add-or-load-translations

How to restrict access of my react build static files?

I have created the build by npm run build and hosted the build folder on a server.
My problem is that I can see the static files by their paths. Eg - https://[mydomain.com]/static/js/11.ba24d9f9.chunk.js2
While if this file doesn't exist(hit a random url on this domain, eg - https://[mydomain.com]/abaknan),
it will render my 404Component because of react-router * entry.
Is it possible to block this chunk route and show 404component ?
React is a Javascript library for UI rendering on the client-side. So, it requires all the compiled JS loaded into the document in order to render the components.
If you are using any sensitive information on your page. Please secure those in your backend application.
The compiled JS chunk files are necessary to render the page. So, they must be accessible from wherever you're requesting the page. Other endpoints return your custom 404 page because the file wasn't found by React Router. Blocking chunk routes is not possible from your UI framework, you will need to add those rules on your server.

django rest + react js how can I access directly the url of react route?

My project has django-rest framework backend api server and reactjs frontend.
there is index.html of reactjs file in django static/file directory.
So, I can access the react page by the url "backend_url.com/static/index.html".
problem is I want to access the url of react router.
"backend_url.com/static/index.html/public/log-in-page/" like this. to go directly to react log-in page.
but, the server try to find "static/index.html/public/log-in-page/" directory. so It will fail.
Finally, what I want to develop is to go directly the specific react page and pass over parameters by the url.
how can I reach that?
You will have to configure your webserver so that it serves index.html regardless of the rest of the URL. Depending on your webserver, this will done one way or another.
However, if you are using Django, I suggest that you use Django views to render your page. You could be saving your React page as a template, and render the template from the view.
# urls.py
from django.urls import re_path
url_patterns = [
re_path(r'^/your/app/?.*', views.app)
]
# views.py
from django.shortcuts import render
def app(request):
return render(request, 'index.html')

Resources