Component Shadowing
provides a powerful API for customizing the rendering of components
and even entire pages. For example, changing the logo might involve
shadowing that component by creating your custom implementation
in a file named src/gatsby-theme-blog/components/logo.js
. Now,
with recent improvements shipped to Gatsby core, you can extend
any component or file in the src
directory.
This means that you can import the component you’re shadowing and then render it. Consider a scenario where you have a custom Card component that you want to wrap the author’s bio in.
Before component extending was added this meant you had to copy over the entire component implementation from the theme to wrap it with your Card. It might look something like:
This workflow isn’t too bad, especially since the component is relatively straightforward. However, it could be optimized in scenarios where you want to wrap a component or pass a different prop without having to worry about the component’s internals.
Importing the Shadowed Component
In the above example it’d be preferable to be able to import the Author component and wrap it with your Card.
Now, that component extending has been added you can do the following instead:
This is a quick and efficient way to customize rendering without needing to worry about the implementation details of the component you’re looking to customize. Extending the shadowed component means you can use composition, leveraging a great feature from React.
Applying New Props
In some cases there could be a component with different variants without an API to modify it outside of shadowing. With component extending you can import that component and then add your new prop to change it.
If NewsletterButton
accepts a variant
prop which changes the
look and colors of the button, you can use it when you extend
the component. Below, NewsletterButton
is re-exported and
variant="link"
is added in the shadowed file to override its
default value.
Using the CSS Prop
In addition to passing a different prop to a component you’re extending, you might want to apply CSS using the Emotion CSS prop. This will allow you to change the styling of a particular component without changing any of its functionality.
Note: For this approach to work NewsletterButton
has to accept a
className
property.
Change an Object
Another use case might be changing a theme.js
file that a Gatsby
Theme uses to set colors globally.
This provides a nice interface to extend an object if you want to change a couple values from the defaults.
Conclusion
If you need to make a small change to an existing component or add an additional prop, extending the component via shadowing can be an effective pattern.