Hello @hericlis,
It looks like you’re encountering a styling issue where the styles for the footer
model are affecting the page model, causing unintended overrides. This is likely because Builder.io injects global styles that are applied across all components by default, and both the page
and footer
models are sharing the same global styles. Since these styles are not scoped to specific components, they can conflict with each other when rendered on the same route.
Here are some approaches to address this issue:
1. Isolate Styles for Each Model (Scoped Styles)
One way to isolate styles between the models is by applying CSS scoping or using CSS Modules or Styled Components to ensure styles are not globally applied. You can also wrap each Builder.io model in a container element with a unique class and scope the styles to that container.
Option A: CSS Modules (or styled-components)
If you’re using CSS Modules or Styled Components, you can scope the styles per component. For example:
// PageModel.tsx
import styles from './PageModel.module.css';
const PageModel = ({ content }) => {
return (
<div className={styles.pageModel}>
{/* Render content here */}
</div>
);
};
export default PageModel;
/* PageModel.module.css */
.pageModel {
/* page-specific styles */
}
.pageModel .builder-button {
/* specific styling for buttons on page */
}
Option B: Scoped Classes with plain CSS
If you’re using plain CSS, you can scope your styles by applying a unique class to the top-level container for each model:
// PageLayout.tsx
import { BuilderComponent } from '@builder.io/react';
const PageLayout = ({ footerModel, pageModel }) => (
<div>
<div className="page-container">
<BuilderComponent model="page" content={pageModel} />
</div>
<div className="footer-container">
<BuilderComponent model="footer" content={footerModel} />
</div>
</div>
);
export default PageLayout;
/* Scoped styles */
.page-container .builder-button {
/* styles specific to page */
}
.footer-container .builder-button {
/* styles specific to footer */
}
2. Dynamically Control the Injection of Builder.io Styles
Builder.io automatically injects a global stylesheet containing all the styles for each model. If the same styles are being injected twice, it could be because the stylesheet is being applied to both the page and footer, causing conflicts.
One way to prevent this is to dynamically inject styles only for the specific model that is being rendered. You could control the loading of these styles by using useEffect
or by manually controlling the injection based on the model.
Here’s a possible solution for conditionally loading the styles for Builder.io:
Example: Dynamically Inject Styles for Each Model
import { useEffect } from 'react';
import { BuilderComponent, builder } from '@builder.io/react';
const PageLayout = ({ pageModel, footerModel }) => {
useEffect(() => {
// Dynamically inject page-specific styles
const pageStylesheet = document.createElement('link');
pageStylesheet.rel = 'stylesheet';
pageStylesheet.href = builder.getAllContent({ model: 'page' })[0]?.data?.stylesUrl;
document.head.appendChild(pageStylesheet);
return () => {
document.head.removeChild(pageStylesheet); // Clean up when the component is unmounted
};
}, []);
return (
<div>
<BuilderComponent model="page" content={pageModel} />
<BuilderComponent model="footer" content={footerModel} />
</div>
);
};
3. Prevent Duplicate Style Injection
Another way to manage this issue is by ensuring that Builder.io stylesheets are not injected multiple times. If Builder.io is injecting the same stylesheet for both the page
and footer
models, you can manually control when styles are injected. Ensure that the styles for the page
model are loaded first and only inject the styles for the footer
model once.
You can check for the existing <link>
tag in the head to avoid injecting it again:
useEffect(() => {
const existingStylesheet = document.querySelector("link[href*='builder.io']");
if (!existingStylesheet) {
const pageStylesheet = document.createElement('link');
pageStylesheet.rel = 'stylesheet';
pageStylesheet.href = builder.getAllContent({ model: 'page' })[0]?.data?.stylesUrl;
document.head.appendChild(pageStylesheet);
}
return () => {
if (existingStylesheet) {
document.head.removeChild(existingStylesheet);
}
};
}, []);
4. Use Custom CSS to Overwrite Unwanted Styles
If necessary, you can also use !important to override unwanted styles, although this is generally not the most elegant solution. You could, for instance, enforce your page’s styles over the footer’s styles for specific elements that are getting overridden.
.builder-button {
all: unset !important; /* Use !important only when necessary */
}
5. Using Builder.io’s Advanced Layout and Nesting Capabilities
Builder.io allows for powerful nesting of components, so consider moving the footer out of the page-level model and nesting it within the page model itself (if that fits your design). This way, the styles for the page and footer are confined to one scope, which may help reduce issues with conflicting styles.
Summary
To fix this issue, I recommend using one or more of the following strategies:
- Scope styles for each Builder.io model (e.g., using CSS Modules, scoped classes, or Styled Components).
- Dynamically inject styles only when needed, based on the rendered model.
- Control the injection of Builder.io stylesheets to avoid duplication.
- Use custom CSS overrides as a last resort if necessary.
Isolating the styles for each content model and controlling the injection of the stylesheets should solve the problem of conflicting styles between your page
and footer
models.
Let me know if you need more detailed examples or further assistance!