Reputation: 483
I am setting up a simple Nextjs boilerplate but can't seem to get the styled-components to work. In my file Header.tsx:
// Core Module Imports
import Link from "next/link";
import * as React from "react";
// Styled-Component Imports
import styled from "../theme/theme";
class Header extends React.Component {
render() {
return (
<div>
<Link href="/about">
<a>About Us</a>
</Link>
</div>
);
}
}
const StyledHeader = styled(Header)`
width: 100vw;
height: 10vh;
background: #2a2c39;
color: #ff0000;
link-style: none;
`;
export default StyledHeader;
As you can see, I set up a simple Header component and then below I used styled() to define my css. In my file Index.tsx:
// Core Module Imports
import * as React from "react";
import StyledHeader from "../components/Header";
class Index extends React.Component {
render() {
return (
<div>
<StyledHeader />
<p>Test Change</p>
<div>Example Div</div>
</div>
);
}
}
export default Index;
Obviously I am doing something wrong because it is not working and all I get it an unstyled link. Can anyone point me in the right direction?
Upvotes: 4
Views: 9125
Reputation: 2044
I don't know if this is what you're searching for but styling a Next Link is pretty easy
import Link from 'next/link'
const StyledLink = styled(Link)`
text-decoration: none;
color: white;
`
and then use it like
<StyledLink href={route.path}>
{route.name}
</StyledLink>
Upvotes: 1
Reputation: 21
TL;DR:
Create a _document.js
file in your /pages
folder and paste this in. It should work immediately 😁
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
}
} finally {
sheet.seal()
}
}
}
If you want styled-components to work automatically on every page/component, you "can create a ServerStyleSheet and add a provider to your React tree, that accepts styles via a context API." In Nextjs, you would do so by adding it to your _document.js
file...
You can read about it more if you follow these links:
Thankfully there's already a working example you can use from the styled-components people themselves!
Check it out here: https://github.com/vercel/next.js/blob/canary/examples/with-styled-components/pages/_document.js
Upvotes: 1
Reputation: 483
For anyone that sees this and has a similar issue, check out this: https://github.com/zeit/next.js/issues/1942#issuecomment-313925454
Fixed my issue.
Hey guys. At version 3.0.1-beta.13+, you could set passHref to Link (as a boolean property) to expose its href to styled-components (or any other library that wraps its tag).
const StyledLink = styled.a`
color: red;
background: blue;
`
export default ({ href, name }) => (
<Link prefetch href={href} passHref>
<StyledLink>{name}</StyledLink>
</Link>
)
There are solutions in the GitHub issue for people using next-routes
.
Upvotes: 3
Reputation: 14788
You need to pass this.props.className
into the root element of Header
so the styled wrapper can pass a generated class name in:
class Header extends React.Component {
render() {
return (
<div className={this.props.className}>
<Link href="/about">
<a>About Us</a>
</Link>
</div>
);
}
}
Upvotes: 2