React route adds margin to the page - html

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).

Related

How to inject tailwind css into an iframe without using play cdn of tailwind

I'm working with svelte and made a chat widget, for styling I used tailwindcss.
the main problem with the chat widgets are you have to render them in an iframe so that it doesn't disturb the css of its remote site. so I achieved loading it inside iframe but it rendered without tailwind styles.
// main.ts is my file where I declared the iframe
import './app.css';
import App from './App.svelte';
// you can ignore this interface if you find it confusing
interface IWidget {
iframeContainer: HTMLElement | null;
init: (props: any) => void;
createContainer: () => void;
handleMessage: (event: MessageEvent) => void;
setupListeners: () => void;
}
const app = (() => {
// new App({
// target: document.getElementById('app'),
// });
const iframeContainer = document.createElement('div');
iframeContainer.id = 'my-chat-widget';
document.body.appendChild(iframeContainer);
// create iframe
const iframe = document.createElement('iframe');
iframe.id = 'my-chat-iframe';
iframe.srcdoc = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Support</title>
<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=Roboto:wght#100;300;400;500;700&display=swap"
rel="stylesheet"
/>
</head>
<body>
<div id="my-widget"></div>
</body>
</html>`;
document.getElementById('my-chat-widget').appendChild(iframe);
const iframeWindow: HTMLIFrameElement =
document.getElementById('my-chat-iframe');
document.getElementById('my-chat-iframe').onload = () => {
new App({
target: iframeWindow.contentWindow.document.getElementById('my-widget'),
});
};
})();
export default app;
the file above is similar to index.tsx in react
Basically I'm directly targeting my svelte app into the iframe, only the problem I'am facing is the tailwind css is not loading.
methods I tried
adding Play CDN link from tailwind into head of above file.
(this worked but not feasible as production build)
directly linking the app.css into head of above file.
(this also worked but only in dev mode because the bundler adds its content hash, I want it to be production ready)

React project is not displaying text as I intend

I am using Material UI TextInput component with a placeholder prop that passes the text "Contraseña"; The letter ñ in the word is not rendering as intended, but as \fx1. The HTLM header have meta UTF-8 and I am using parcel 2.0.0-rc.0 as my bundler
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="APP"
content="web site created using react"
/>
<script src="~/src/index.js" type="module"></script>
<title>App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
index.js
import React, { StrictMode } from "react";
import ReactDOM from "react-dom";
import TextField from "#material-ui/core/TextField";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<TextField color="secondary" margin="none" placeholder="Contraseña" />
</StrictMode>,
rootElement
);
The problem seems to be related to the use of Parcel 2 RC (Bug report). It is important to notice that the bad encoding occurs only in attribute values; a temporary solution is to put brackets around the string attribute value:
<TextField color="secondary" margin="none" placeholder={"Contraseña"} />

How to fetch multiple google fonts

I'm working on a personal project in NextJS which uses around 5 Google fonts.
The fonts are being fetched only if the page New is reloaded or if I navigate to the page using <a></a> tag instead of <Link></Link>.
This is my current code for the page that requires the fonts,
export async function getStaticProps() {
const fonts = getFontNames(); // returns a static list of strings like ['Monserrat', 'Product Sans', ...].
const fontsLink = "https://fonts.googleapis.com/css2?family=" + fonts.map(cV => cV.replace(/ /g, '+')).join('&family=') + "&display=swap"
return {
props: {
fonts,
fontsLink
}
}
}
export default function New({ fonts, fontsLink }) {
return (
<div className={styles.container}>
<Head>
<title>New</title>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href={fontsLink} rel="stylesheet" />
</Head>
...
</div>
}
This is how I navigate to the page New ,
<Link href="/new">
<a className={styles.card}>
<h2>New →</h2>
</a>
</Link>
Make sure you've disabled browser cache in the network tab before testing fonts.
import PageLayout from "../components/Page/PageLayout"
import Head from "next/head"
export default function About({ fonts, fontsLink }) {
return (
<Head>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href={fontsLink} rel="stylesheet" />
</Head>
)
}
export async function getStaticProps() {
const fonts = ["Monserrat", "Product Sans", "Girassol"]
const fontsLink =
"https://fonts.googleapis.com/css2?family=" +
fonts.map((cV) => cV.replace(/ /g, "+")).join("&family=") +
"&display=swap"
return {
props: {
fonts,
fontsLink,
},
}
}
Using either means of navigation loads the fonts for me.
<Link href="/About">About</Link>
<Link href="/About">
<a>
<h2>About page using Link</h2>
</a>
</Link>

CSS loads after HTML using React and SemanticUI

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.

How to make vantajs wave work with react app

I am using vantajs wave library and my issue is how do i get the waves to continue to render on a CSS selector after I click through the tablinks of my react app?
The first error I get is on Brave browser when it says:
"three.r92.min.js:28 Uncaught TypeError: Cannot read property 'precision' of null"
and doesn't render the wave at all initially.
However, if i go to Google Chrome and look at the background of my selected element there is the wave effect that I implemented provided by https://www.vantajs.com/?effect=waves#(backgroundAlpha:1,color:2105474,shininess:30,waveHeight:15,waveSpeed:1,zoom:1)
But then, after I switch from the home tab to another tab, then come back to home (where my selected element is), the wave effect is no longer behind the selected element as it says:
"vanta.waves.min.js:161 [VANTA] Cannot find element .showcase__container
Here is my HTML:
<meta charset='utf-8' lang="EN-US">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="./src/three.r92.min.js"></script>
<script src="https://www.vantajs.com/dist/vanta.waves.min.js"></script>
<link rel="stylesheet" href="./css/style.css">
<title>DigitalWebFlex</title>
</head>
<body>
<div id='root'></div>
<script type='text/javascript' src='/dist/bundle.js' charset='utf-8'></script>
<script>
VANTA.WAVES('#showcase__container');
</script>
</body>
And my React:
<div className="showcase__container" id="showcase__container">
<button className="button button--animated button--white" onClick={this.setPagePortfolio}>Portfolio</button>
</div>
Thanks in advance!
hey you can install vanta using npm i vanta
and include three.js in the head
and then
import React from 'react'
import WAVES from 'vanta/dist/vanta.waves.min'
class MyComponent extends React.Component {
constructor() {
super()
this.vantaRef = React.createRef()
}
componentDidMount() {
this.vantaEffect = WAVES({
el: this.vantaRef.current
})
}
componentWillUnmount() {
if (this.vantaEffect) this.vantaEffect.destroy()
}
render() {
return (
<div ref={this.vantaRef}>
/* Foreground content goes here */
</div>
)
}
}
This should help, You can refer to this page and Vanta.js README for a better understanding