Ordering problem using css import alongside styled components in nextjs app - next.js

I am using NextJS and when I use direct css import ...css alongside a styled-component createGlobalStyle. My direct css imports are always included last in my html causing some overriding issues that I've setup in GlobalStyles.
How can I resolve this?
rendered html
<head>
<link href="/_next/static/chunks/main.js?ts=1609163560022">
<style></style> // global styled component
<style></style> // bootstrap imported after global styled component
</head>
_app.js
import { ThemeProvider } from "styled-components";
import 'bootstrap/dist/css/bootstrap.min.css' // this is always loaded last <head>
import GlobalStylesfrom 'styles/global'; // this is always loaded first in <head>
const theme = {
...
};
export default function App({ Component, pageProps }) {
return (
<ThemeProvider theme={theme}>
<GlobalStyles/>
<Component {...pageProps} />
</ThemeProvider>
)
}
_document.js
import Document, { Html, Head, Main, NextScript } from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static getInitialProps({ renderPage }) {
const sheet = new ServerStyleSheet();
const page = renderPage(App => props =>
sheet.collectStyles(<App {...props} />)
);
const styleTags = sheet.getStyleElement();
return { ...page, styleTags };
}
render() {
return (
<Html>
<Head>{this.props.styleTags}</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}

Related

How to migrate MUI _document.js and _app.js to next.js13 app/layout.js

I found these documents (_document.js, _app.js) but it is not so clear to me how it should be defined.
This is the layout.js file I started building, Is there something missing, or something that needs fixing?
Thanks.
app/layout.js
import React from 'react'
import PropTypes from 'prop-types'
import { ThemeProvider } from '#mui/material/styles'
import CssBaseline from '#mui/material/CssBaseline'
import { CacheProvider } from '#emotion/react'
import theme, { roboto } from '../utility/theme'
import Head from './Head'
import createEmotionCache from '../utility/createEmotionCache'
const clientSideEmotionCache = createEmotionCache()
export default function RootLayout({ children }, props) {
const { Component, cache = clientSideEmotionCache, pageProps } = props
return (
<html className={roboto.className}>
<CacheProvider value={cache}>
<Head />
<body>
<ThemeProvider theme={theme}>
<CssBaseline />
<Component {...pageProps}>{children}</Component>
</ThemeProvider>
</body>
</CacheProvider>
</html>
)
}
RootLayout.propTypes = {
Component: PropTypes.elementType.isRequired,
emotionCache: PropTypes.object,
pageProps: PropTypes.object.isRequired,
}

How do I pass a property (specifically "theme") to "Components" in a next.js app?

I have a next.js app and this is the _app.tsx file:
import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { createTheme } from '#arwes/design'
import { ThemeProvider, Global, css } from '#emotion/react'
import { globalStyles, blueOnBlack } from '../shared/styles.js'
function MyApp({ Component, pageProps }: AppProps) {
const theme = createTheme();
return (
<ThemeProvider theme={theme}>
{globalStyles}
<div style={blueOnBlack(theme)}>
Futuristic Sci-Fi UI Web Framework
</div>
<Component {...pageProps} />
</ThemeProvider>
)
}
export default MyApp
The problem is that I need to access theme in index.tsx. So how do I pass this into Component?
In the children components, use:
const theme = useContext(ThemeProvider)
I was eventually able to access the parent's theme via emotion's useTheme(). I have to actually build the component outside of the render area of the page's exported function. In the index.tsx file for example:
function SomeText(props: any) {
const theme = useTheme()
return <div style={{ color: theme.palette.primary.dark3 }} {...props} />
}
// Now that above function "SomeText" can be accessed as a component in "Home"
const Home: NextPage = () => {
return (
...
<SomeText className={styles.description}>
Get started by editing{' '}
<code className={styles.code}>pages/index.tsx</code>
</SomeText>
...
)
}
export default Home
And that works because the text above is set to "dark3" color.

Google font loads very weirdly after the deployment to the vercel

I have deployed the next js app to the server using vercel. I have referenced the two google fonts in _document.js. While I am running the app locally both font load without any problem.
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document
{
static async getInitialProps(ctx)
{
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render()
{
return (
<Html>
<Head>
<link href="https://fonts.googleapis.com/css2?family=Crete+Round&family=Work+Sans:wght#500;600&display=swap" rel="stylesheet" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
index.js
import Head from "next/head";
import Script from "next/script";
import Banner from "../components/Banner";
import { fetchAPI } from "../lib/api";
import Articles from "../components/Articles";
export default function Home({ articles })
{
return (
<>
<Head>
<title>Life Sciencify - Explore the mystery of life with Science! </title>
</Head>
<Articles articles={articles} />
</>
);
}
export async function getServerSideProps()
{
const [articlesRes] = await Promise.all([
fetchAPI("/posts", { populate: ["cover", "category"] })
]);
console.log(articlesRes)
return {
props: {
articles: articlesRes.data
}
};
}
app.js
import Script from "next/script";
import "bootstrap/dist/css/bootstrap.css";
import "../styles/globals.css";
import { useEffect } from "react";
import Header from "../components/Header";
import SearchBlock from "../components/SearchBlock";
import Footer from "../components/Footer";
function MyApp({ Component, pageProps })
{
useEffect(() =>
{
import("bootstrap/dist/js/bootstrap");
}, []);
return (
<>
<Component {...pageProps} />
</>
);
}
export default MyApp;
After the deployment it is showing the weird behavior.
Initially When I am in the home page the page doesn't load any font.
Now, when I click the link Post1 or Post 2, it will be redirected to the detail page.
at first font is not loaded in this page too.
Now, after the page refresh the font gets loaded.
Now, when I go to the back page in the browser, the home page will have the font loaded. But again when the page is refreshed the font will be gone.
What is the causing the weird behavior?
I am running the application in the next js version of "12.1.6".
Referenced:
google-font-display
font-optimization
In the _document.js i used two google fonts separately and it is working now.
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document
{
static async getInitialProps(ctx)
{
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render()
{
return (
<Html>
<Head>
<link href="https://fonts.googleapis.com/css2?family=Work+Sans:wght#500;600&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Crete+Round&display=swap" rel="stylesheet" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
and in index.js, change server side rendering to static props:
export async function getStaticProps()
{
const [articlesRes] = await Promise.all([
fetchAPI("/posts", { populate: ["cover", "category"] })
]);
console.log(articlesRes)
return {
props: {
articles: articlesRes.data
}
};
}
After this changes I deployed to vercel it worked fine, again after some time i changes to getServerSideProps, it was not working. So, the culprit was getServerSideProps with google font.

How to use TailwindCSS with Material UI?

I am using Next.js with Material UI. I am having troubles with using Tailwind with MUI. I've been following this guide but it still doesn't work. The file loads but the classes just don't apply. If someone could help, that would be wonderful!
My Tailwind Config
module.exports = {
important: "#__next",
content: ["./pages/**/*.{js,jsx}"],
theme: {
extend: {},
},
plugins: [],
}
My _app.js
//import '../styles/globals.css'
//function MyApp({ Component, pageProps }) {
// return <Component {...pageProps} />
//}
//export default MyApp
import '../styles/edit.css';
import * as React from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';
import { ThemeProvider, StyledEngineProvider } from '#mui/material/styles';
import CssBaseline from '#mui/material/CssBaseline';
import { CacheProvider } from '#emotion/react';
import theme from '../config/themeConfig';
import createEmotionCache from '../functions/createEmotionCache';
import Layout from "../components/Layout";
//import '../styles/tailwind.css';
// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
export default function MyApp(props) {
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
return (
<Layout>
<CacheProvider value={emotionCache}>
<Head>
<meta name="viewport" content="initial-scale=1, width=device-width" />
</Head>
<ThemeProvider theme={theme}>
<StyledEngineProvider injectFirst>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<Component {...pageProps} />
</StyledEngineProvider>
</ThemeProvider>
</CacheProvider>
</Layout>
);
}
MyApp.propTypes = {
Component: PropTypes.elementType.isRequired,
emotionCache: PropTypes.object,
pageProps: PropTypes.object.isRequired,
};
Thanks!
You didn't follow the guide ( https://mui.com/material-ui/guides/interoperability/#tailwind-css ) correctly.
In your tailwind.config.js file you need to set the corePlugins parameter to disable the preflight CSS. The preflight CSS is overriding some of the styles of MUI.

How to add Tailwind CSS scroll-smooth class to Next.js

I want to add scroll behaviour smooth to my Next.js app, and the Tailwind CSS documentation instructs us to add the utility class in <html/>.
<html class="scroll-smooth ">
<!-- ... -->
</html>
This file does not contain an html tag:
import Head from "next/head";
import "#material-tailwind/react/tailwind.css";
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
return (
<>
<Head>
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
</Head>
<Component {...pageProps} />
</>
);
}
export default MyApp;
How and where can I add the smooth-scroll utility class in my project?
The simplest solution, do it from your globals.css file...
#tailwind base;
#tailwind components;
#tailwind utilities;
#layer base {
html {
#apply scroll-smooth;
}
}
Use a custom _document.js and add it there - Here is an explanation of what it does -
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html class="scroll-smooth">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
For those who will be using nextjs 13 . You can simply add the class (clasName) in the parent layout file like below :-
import '../styles/globals.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html className='scroll-smooth'>
<head />
<body>{children}</body>
</html>
)
}

Resources