Just a little exmaple of implementing dark mode functionality in Next.js with styled-components using Rob Morieson's approach with CSS variables
For this purpose we are extending the <Document />
and injecting the server side rendered styles into the <head>
, and also adding the babel-plugin-styled-components
(which is required for server side rendering). Additionally we set up a global theme for styled-components using NextJS custom <App>
component.
Execute create-next-app
with npm or Yarn to bootstrap the example:
npx create-next-app --example with-styled-components with-styled-components-app
# or
yarn create next-app --example with-styled-components with-styled-components-app
Deploy it to the cloud with Vercel (Documentation).
When wrapping a Link from next/link
within a styled-component, the as prop provided by styled
will collide with the Link's as
prop and cause styled-components to throw an Invalid tag
error. To avoid this, you can either use the recommended forwardedAs prop from styled-components or use a different named prop to pass to a styled
Link.
Click to expand workaround example
components/StyledLink.js
import Link from 'next/link'
import styled from 'styled-components'
const StyledLink = ({ as, children, className, href }) => (
<Link href={href} as={as} passHref>
<a className={className}>{children}</a>
</Link>
)
export default styled(StyledLink)`
color: #0075e0;
text-decoration: none;
transition: all 0.2s ease-in-out;
&:hover {
color: #40a9ff;
}
&:focus {
color: #40a9ff;
outline: none;
border: 0;
}
`
pages/index.js
import StyledLink from '../components/StyledLink'
export default () => (
<StyledLink href="/post/[pid]" forwardedAs="/post/abc">
First post
</StyledLink>
)