I have a create-react-app project that uses SemanticUI for styling. My App component is the following:
import React from 'react';
import './App.css'
import { LandingComponent } from '../components/landing/LandingComponent/index'
import { LoginComponent } from '../components/login/LoginComponent/index'
import { DashboardComponent } from '../components/dashboard/DashboardComponent/index'
import { MenuComponent } from '../components/menubar/MenuComponent/index'
import { BrowserRouter as Router, Route, Link } from "react-router-dom"
const App: React.FC = () => {
return (
<>
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/semantic-ui#2.4.2/dist/semantic.min.css" />
<MenuComponent />
<Router>
<Route exact path="/" component={() => <LandingComponent />} />
<Route exact path="/login" component={() => <LoginComponent />} />
<Route exact path="/dashboard" component={() => <DashboardComponent />} />
</Router>
</>
);
}
export default App;
Whenever I am working in development mode, I will be able to see the raw HTML for a few milliseconds before the styling kicks in. I figured this would be solved after I build an optimized build using npm run build
However, in a production build, I am having the same issue. I was reading other accounts of people with the same issue, and some recommended using mini-css-extract-plugin. However, I wanted to know if there was a solution to this without adding any additional plugins to my project?
Yes, what you want to achieve is to load the CSS resource as a render blocking resource, which means the browser will load the resource first before rendering the content.
This has nothing to do with React or your build tooling, but rather how web pages work.
This can be achieved by moving the element from your App component to your document . So, move your line to the index.html file that is in the public folder.
Your index.html will then look something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
...
<title>React App</title>
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/semantic-ui#2.4.2/dist/semantic.min.css" />
</head>
<body>
...
Please note, that from web performance point-of-view it is recommended to add the CSS resource only after your title attribute, so that the title gets "rendered" before the browser starts fetching the CSS resource.
Related
This doesn't seem to make any sense, but I'll explain and add code.
Yesterday while working on my app I suddenly realized that there are unnecessary margins on the borders of the page. The type that would appear if you didn't reset the margin and padding.
I've tried eliminating things at the source, and noticed that I only get those margins once I add a route (doesn't matter which one). When there is no route, no margins.
I've tried checking one of the pages (maybe I've made some mistake in all of them) and after seeing no issue, I've decided to create a test page which is completely empty. If I add the route to that page, the margins appear. If I don't, they don't.
What could be the reason?
Attaching code below.
index.tsx
import React from "react";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import { store } from "./store/store";
import { App } from "./App";
import "./styles.css";
const container = document.getElementById("root")!;
const root = createRoot(container);
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
styles.css
* {
margin: 0px;
padding: 0px;
font-family: Cabin;
}
App.tsx
import { Route } from "react-router-dom";
import Wrapper from "./wrapper";
import {
TestPage,
} from "./pages";
export function App() {
return (
<Wrapper data-test="app">
<Route path="/" element={<TestPage />} />
</Wrapper>
);
}
TestPage (it is import and rexported from an index.ts file, and again from the main "pages" index file. Those files are simply re-exporting the component below.
import { Box } from "rebass";
import { TestPresentational } from "../presentational";
export const TestContainer = () => {
return <Box>Hola</Box>;
};
Just in case, this is my public index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cabin:wght#400;500;600;700&family=Open+Sans:wght#300;400;500;600;700;800&display=swap" rel="stylesheet">
<title>Travel buddy</title>
</head>
<body>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&libraries=places"></script>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
EDIT:
It's been asked if it is possible the the Box component added the margins.
I've tried returning this from App.tsx instead of the wrapper component, and had no issues.
return (
<Box
sx={{
width: "100vw",
height: "100vh",
backgroundColor: "blue",
margin: "0px",
padding: "0px",
}}
></Box>
);
So no, the component is not the issue. An interesting thing that campe up though, is if I've returned that without commenting out the wrapper return (but making its code unreachable) I got the margins again.
I had a new library that imported a css file that added padding to page. Found it thanks to #Andre suggestion (never got comfortable with the browser inspector but this forced me to, so glad it happened).
I'm trying to override the primary color in Bootstrap but it just doesn't work. Btw I'm using NextJS.
This is my "globals.scss" which I have imported in "_app.js".
$primary: black;
#import 'bootstrap/scss/bootstrap';
And I have imported Bootstrap in index.js like this
import 'bootstrap/dist/css/bootstrap.css'
I tried looking it up but everything I tried didn't work.
What I've tried:
Importing functions, variables, and mixins from Bootstrap SCSS.
Rearranging the imports.
Importing bootstrap/scss/bootstrap.scss to "_app.js"
But I've noticed that in the inspector it says my primary color is black but then right above it changes back to the original:
Below:
Above:
How to override Bootstrap variables in a Next.js project
Let's create an app and try to change the $primary color from default to black.
App structure:
Code:
index.js
import Head from 'next/head'
import styles from '../styles/Home.module.css'
export default function Home() {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name='description' content='Generated by create next app' />
<link rel='icon' href='/favicon.ico' />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>
Welcome to <a href='https://nextjs.org'>Next.js!</a>
</h1>
<button type='button' className='btn btn-primary mt-4'>Primary</button>
</main>
</div>
)
}
_app.js
import '../styles/globals.css'
import { useEffect } from 'react'
function MyApp({ Component, pageProps }) {
useEffect(() => {
require('bootstrap/dist/js/bootstrap.bundle.min.js');
}, []);
return <Component {...pageProps} />
}
export default MyApp
globals.scss
$primary: black;
#import '../node_modules/bootstrap/scss/bootstrap';
Screenshot:
I think the problem of your codes is about the order of importing files. If you use globals.scss file to change bootstrap default values, Then you must import that file after your main bootstrap file. I'm not sure about the project structure you have, but for example if you imported Bootstrap in index.js file, change that file from just this:
import 'bootstrap/dist/css/bootstrap.css'
To something like this:
import 'bootstrap/dist/css/bootstrap.css'
import 'your/path/to/globals.scss'
Maybe that overrides the bootstrap file with your custom file.
I'm embedding a request form. I want to click a button in react to open the form, then add a button to go back/exit. Ive added the HTML tags into index.html but I'm having a hard time with control. I toggle the display: none/block to get it to appear/ disappear which works fine (also have to toggle display for all of the react app so only the form is shown.).
The Html I'm trying to embed has 3 tags. I'm not able to find an answer of how to use dangerouslySetInnerHTML with multiple tags.
I've also just tried to use dangerouslySetInnerHTML twice and just gave the react div the needed reference id. No luck, just a blank white page.
<div id="f6f2802e-49e8-477b-b405-8b2b18dded97"></div>
<link rel="stylesheet" media="screen" href="https://d3ey4dbjkt2f6s.cloudfront.net/assets/external/work_request_embed.css" />
<script src="https://d3ey4dbjkt2f6s.cloudfront.net/assets/static_link/work_request_embed_snippet.js" clienthub_id="f6f2802e-49e8-477b-b405-8b2b18dded97" form_url="https://clienthub.getjobber.com/client_hubs/f6f2802e-49e8-477b-b405-8b2b18dded97/public/work_request/embedded_work_request_form"></script>
12 hours of trying.
(https://codesandbox.io/s/l9qmrwxqzq)
This worked pretty much immediately. Once I found it.
'''
import React from "react";
import ReactDOM from "react-dom";
import { Helmet } from "react-helmet";
import "./styles.css";
function App() {
return (
<div className="App">
<h1>Check if Helmet works as expected with script tags</h1>
<p>Check console output - you will see $ is undefined</p>
<Helmet>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"
/>
<script>
{`
console.log('Test', typeof $);
`}
</script>
</Helmet>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
'''
My final product
'''
import React from "react";
import { Helmet } from "react-helmet";
export default class Jobber extends React.Component {
render() {
return (
<div className="Application" id="f6f2802e-49e8-477b-b405-8b2b18dded97">
<Helmet>
<div id="f6f2802e-49e8-477b-b405-8b2b18dded97"></div>
<link
rel="stylesheet"
media="screen"
href="https://d3ey4dbjkt2f6s.cloudfront.net/assets/external/work_request_embed.css"
/>
<script
src="https://d3ey4dbjkt2f6s.cloudfront.net/assets/static_link/work_request_embed_snippet.js" clienthub_id="f6f2802e-49e8-477b-b405-8b2b18dded97" form_url="https://clienthub.getjobber.com/client_hubs/f6f2802e-49e8-477b-b405-8b2b18dded97/public/work_request/embedded_work_request_form"
/>
</Helmet>
</div>
);
}
}
'''
I'm having some trouble with a sticky footer in react. I implemented the flexbox solution I saw on CSS Tricks, but the problem is The footer is at the bottom of the main App component, but the App component is not at the bottom of the body. Here's a picture that illustrates this problem:
Some code:
In the render function of my App component I'm returning this:
render() {
return (
<div className="App">
<div className="all-but-footer">
<Header />
<main className="content">
<Switch>
<Redirect from="/" to="/bio" exact />
<Route path="/bio" exact component={Bio} />
</Switch>
<Route path="/videos" exact component={Videos} />
<Route path="/gallery" exact component={Gallery} />
<Route path="/magnet-podcast" exact component={MagnetPodcast} />
<Route path="/contact" exact component={Contact} />
</main>
</div>
<Footer />
</div>
And of course I'm hooking into the root div with:
document.addEventListener('DOMContentLoaded', () => {
const root = document.getElementById('root');
ReactDOM.render(
<Root />, root);
registerServiceWorker();
});
With the root div in my index.html like so:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>Louis Kornfeld</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
In my CSS I tried giving the App a height of 100% and even tried giving the root div in the index.html a height of 100%. The body's only child is the root div, and the root div's child is App, so I figured giving these all height of 100% would stretch the components but nothing has worked.
Any ideas with how I can resolve this problem?
Normally, when you return an element from a component’s render method, it’s mounted into the DOM as a child of the nearest parent node
If you want to to insert a child into a different location in the DOM , You can make use React Portals
The one which worked for me is react-portal you can install it as a project dependency npm install --save react-portal
And inside your component you can :
import { Portal } from 'react-portal';
<Portal>
This text is portaled at the end of document.body!
</Portal>
<Portal node={document && document.getElementById('youCanSelectAnyIdFromTheDOM')}>
This text is portaled into San Francisco!
</Portal>
You can read more about react-portal Here
In my webpack, the entry point of the application is set to index.js:
entry: {
app: [
'react-hot-loader/patch',
'./client/index.js'
]
In node Js, For path / in my application, I am routing it to index.html
from routes.js on server side using:
app.route('/*')
.get((req, res) => {
res.sendFile(path.resolve(`${app.get('appPath')}/index.html`));
});
Above code understandably serves index.html.
But what if I wanted my application routing to be initialized using React-router?
index.html gets rendered but I don't see index.js getting initialized at all.It is defined as entry point in webpack so that should happen ,right?
Problem: To have React-routing initialized which should work once the flow gets to index.js
My routes.js in client folder looks like this :
import React from 'react';
import {Route, IndexRoute} from 'react-router';
import About from './components/About/About';
import Header from './components/Header/Header';
import Outlet from './components/Home/SelectOutlet';
console.log("routes file client")
export default (
<Route path="/" component={Header}>
<IndexRoute component={Outlet}/>
<Route path="about" component={Footer}/>
</Route>
);
and index.js
import 'babel-polyfill'; //certain functions like array.from , set, map can't be transpiled by babel so ue poyfill for that
import React from 'react';
import { render } from 'react-dom';
import { Router, browserHistory } from 'react-router';
import routes from './routes';
//import '../node_modules/bootstrap/dist/css/bootstrap.min.css'; //webpack can import CSS files too
import './styles/styles.css';
render((
<Router history={browserHistory} routes={routes}/>),
document.getElementById('app')
);
console.log("In index js render ")
Consoles in index.js and routes.js never get consoled and the application just serves index.html because of express routing
my webpack file is taken from here: https://github.com/Hashnode/mern-starter
but I don't see bundle.js getting created anywhere with npm start command.
Edit:
error screenshot:
screen 1:
error message
When I click on this error message:
I get all the content from html in js:
<!DOCTYPE html>
<html>
<head>
<title>
ABC
</title>
</head>
<body>
<h1> XYZ</h1>
<div id="app"></div>
<script src="index.js"></script>
</body>
</html>
Well... Are you including
<script src="index.js"></script>
in your index.html?...