I use React SPA Prerender to optimize SEO, and i got this problem :
I have a class called HomeTitleContainer
, specifically used for the Home.jsx
file, which is the home page.
import { Container } from 'react-bootstrap';
import Link from '../immutable/nav/Link';
import './Home.css';
const Home = () => {
return (
<>
<Container className="HomeTitleContainer">
Ma Thématique
</Container>
<Container className="TableOfContentsLink">
<p><Link link={'/cours'} internalLink={true} >- Des cours de mathématiques sur de nombreux sujets</Link></p>
<p><Link link={'/bds-de-jpp'} internalLink={true} >- Des BDs de Jean-Petit</Link></p>
<p><Link link={'/jeux'} internalLink={true} >- Des petits jeux pour s'améliorer</Link></p>
</Container>
</>
);
}
export default Home;
Here is the corresponding css file, Home.css
:
.HomeTitleContainer {
position: relative;
top: 30px;
/* background-color: var(--front-color); */
background-image: linear-gradient(to bottom right, var(--front-color), grey);
border-radius: 10px;
color: var(--links-color);
font-size: large;
padding: 30px;
width: calc(var(--window-width) * 3 / 4);
box-shadow: 20px 20px 5px 5px var(--navbar-color);
margin-bottom: 100px;
}
@media (min-width : 450px) {
.HomeTitleContainer {
width: calc(var(--window-width) * 1 / 2);
top: 50px;
}
}
This HomeTitleContainer
class is not present anywhere else.
But when i generate some html files according to my .rsp.json
file, this class is present in all other generated html files.
To illustrate it, an example with the courses page...
All the pages have a table of content, so I use this file, GenericTableOfContents.jsx
:
import { Container, Row, Col } from 'react-bootstrap';
import Link from '../immutable/nav/Link';
const GenericTableOfContents = ( {items, prefix, title} ) => {
return (
<>
<p className="MainTitle">{title}</p>
<Row>
{
items.map(item => (
<Container key={item.id} className="TableOfContents">
<Col xs={12} md={12}>
<div key={item.id} className="TableOfContentsLink" >
<Link link={`/${prefix}/${item.relativePath}`} internalLink={true} >
<div>{item.title}</div>
</Link>
</div>
</Col>
</Container>
))
}
</Row>
</>
)
}
export default GenericTableOfContents;
You can see that the MainTitle
and the TableOfContents
classes should be one after the other.
But in cours.html
, this sample is present :
<p class="MainTitle">Tous les cours</p>
<div class="HomeTitleContainer container">
<div class="TableOfContents container"> ...
Eventhough it shouldn't have to be there, a div with the HomeTitleContainer
class has been added.
Here is the .rsp.json
:
{
"port": 3000,
"buildDirectory": "./build",
"routes": [
"/",
"/cours",
"/bds-de-jpp",
"/jeux",
"/liens"
]
}
Here is the routes file (AppRoutes.jsx
):
import { Route, Routes } from 'react-router-dom';
import Home from './components/home/Home';
import CoursesTableOfContents from './components/courses/CoursesTableOfContents';
import ChaptersTableOfContents from './components/courses/ChaptersTableOfContents';
import GenericChapter from './components/courses/GenericChapter';
import PdfTableOfContents from './components/pdf-viewer/PdfTableOfContents';
import PDFViewerPage from './components/pdf-viewer/PDFViewerPage';
import GamesTableOfContents from './components/games/GamesTableOfContents';
import Links from './components/links/Links';
import VCard from './components/contact/VCard';
import Error from './components/immutable/Error';
const AppRoutes = ( {courseItems, pdfItems, gameItems} ) => {
return <Routes>
{
process.env.NODE_ENV === 'development' ?
<Route exact path="/" element={<Home />} />
: <Route exact path="/" element={<Home />} />
}
<Route path="/cours" element={<CoursesTableOfContents courseItems={courseItems} />} />
{courseItems.map(courseItem => {
return <Route
key={courseItem.id}
path={`/cours/${courseItem.relativePath}`}
element={<ChaptersTableOfContents courseItem={courseItem} />} />
})}
{courseItems.map(courseItem => (
courseItem.chapters.map(chapter => {
return <Route
key={chapter.id}
path={`/cours/${courseItem.relativePath}/${chapter.relativePath}`}
element={<GenericChapter chapter={chapter} courseItem={courseItem} />} />
})
))}
<Route path="/bds-de-jpp" element={<PdfTableOfContents pdfItems={pdfItems} />} />
{pdfItems.map(pdfItem => (
<Route
key={pdfItem.id}
path={`/bds-de-jpp/${pdfItem.relativePath}`}
element={<PDFViewerPage pdfItem={pdfItem} />} />
))}
<Route path="/jeux" element={<GamesTableOfContents gameItems={gameItems} />} />
{gameItems.map(gameItem => (
<Route
key={gameItem.id}
path={`/jeux/${gameItem.relativePath}`}
element={gameItem.component} />
))}
<Route path="/liens" element={<Links />} />
<Route path="/contact" element={<VCard />} />
<Route path="*" element={<Error />} status={404} />
</Routes>
}
export default AppRoutes;
Added in App.js :
var courseItems = coursesResourceBuilder();
var pdfItems = pdfResourceBuilder();
var gameItems = gamesResourceBuilder();
<div className="App" >
<div className={`${theme} ${font} CopyBook`}>
<BrowserRouter>
<Header courseItems = {courseItems} pdfItems ={pdfItems} gameItems={gameItems} />
<Container className = {` RelativeContainer ${playMode ? "PlayMode" : ''} ${isLoading ? "Blur" : ''} `} >
<AppRoutes courseItems={courseItems} pdfItems={pdfItems} gameItems={gameItems} />
</Container>
<Footer />
</BrowserRouter>
</div>
</div>
And here is the url of the website :
https://ma-thematique.netlify.app
https://ma-thematique.netlify.app/cours
Can somebody can help me please ?
You can try to use Styled Components
to avoid CSS
from applying globally:
import styled from 'styled-components';
const HomeTitleContainer = styled.span`
position: relative;
top: 30px;
background-image: linear-gradient(to bottom right, var(--front-color), grey);
border-radius: 10px;
color: var(--links-color);
font-size: large;
padding: 30px;
width: calc(var(--window-width) * 3 / 4);
box-shadow: 20px 20px 5px 5px var(--navbar-color);
margin-bottom: 100px;
@media (min-width: 450px) {
width: calc(var(--window-width) * 1 / 2);
top: 50px;
}
`;
export default HomeTitleContainer;
Then inside of your Home
component:
import { Container } from 'react-bootstrap';
import Link from '../immutable/nav/Link';
import './Home.css';
import HomeTitleContainer from "./HomeTitleContainer";
import React, {Fragment} from "react";
const Home = () => (
<Fragment>
<Container>
<HomeTitleContainer>
Ma Thématique
</HomeTitleContainer>
</Container>
<Container className="TableOfContentsLink">
<p><Link link={'/cours'} internalLink={true} >- Des cours de mathématiques sur de nombreux sujets</Link></p>
<p><Link link={'/bds-de-jpp'} internalLink={true} >- Des BDs de Jean-Petit</Link></p>
<p><Link link={'/jeux'} internalLink={true} >- Des petits jeux pour s'améliorer</Link></p>
</Container>
</Fragment>
)
export default Home
Can you try this and let us know what the result is?
There are two things which attempt to solve the problem here:
empty tag
instead of a Fragment
- A Fragment allow you to group children without adding extra nodes to the DOM and make your component structure and rendering logic more clear and concise. Empty tags, on the other hand, do not provide these benefits and can lead to additional, unnecessary DOM nodes. This can cause some unusual behavior, especially in older versions of react.CSS
file instead of styled-components
. If you use a CSS
file, the CSS will apply globally and if you are not careful enough, you can easily render a div with a class name that has defined properties in one of your CSS
files.