Loving the idea of NextJS so far! One thing I am not getting is how I can wrap the root app component in a provider such as ApolloProvider or IntlProvider. I have tried in _document.js but it seems that cannot be overwritten so the IntlProvider does not propagate down the component tree.
I tried this in the Document render method:
<IntlProvider locale={locale}>
<Main />
</IntlProvider>
Using: [email protected]
Any ideas?
UPDATE 1/10/2016: I tried @rauchg 's suggestion deciding adding multiple providers in every page was acceptable and it still does not work. I tried a variety of layout components, straight page wrapping, etc and nothing worked. After reviewing the < Main /> component code it looks like it is not passing the right props to children, or the general structural hierarchy is not sufficient. At this point I do not believe it is possible for NextJS to work with ReactIntl.
I'm not familiar with Apollo yet, but there was some discussion at #387 about it.
Also check this example.
@nkzawa Thank you for that reference. I checked the examples but never heard of Styletron so not familiar. I tried using react intl in the same fashion but when I try to use it, I get "
@zachariahtimothy I'm running into the same issue trying to get Apollo to play nice with Next. The fact that we can't pass down context from _document.js
is problematic. Passing it down on every individual page isn't very dry. @nkzawa @rauchg is there any change we can make to the API so that context doesn't get wiped when wrapping <Main />
?
@ads1018 What we recommend is to wrap every page with provider.
@rauchg It seems many people wonder about this. I think we should have a document about this topic.
@nkzawa I think many of us understand that it's recommended we wrap every page with providers. The issue I'm raising is that it makes more sense to wrap our app with a provider once at the root level (preferably in _document.js) as opposed to inside _every single_ page.
If my app had a ton of pages it'd be nicer if they all looked like this:
export default <PostList />
as opposed to this:
export default ApolloHOC()(() => <PostList />) // yuck!
What do you think?
Totally agreed @ads1018 . I am a fan of the DRY principle so for my larger, enterprise app, adding multiple providers to every page is a total non-starter.
Personally I 100% prefer _explicit wrapping_ over "nicer looking". It just scales better (in terms of understanding and the ability of others to work on your stuff), than hidden global files.
The only reason we have _document
is that React can't control the entire markup, otherwise we'd be asking you to wrap everything :D
In my experience as well, you always _think_ that every part of your system abides by the same rules, but you end up finding later that it's not the case.
When I set out to clone HN, it would have been very tempting to create a global layout in _document
for everything.
After all every page seems to have some simple rules, like the navigation bar, background, etc.
Except that the login page is completely different. None of the global "rules" you thought you had apply: fonts, wrapper elements, widths, mobile queries…
_
What did it cost me? Just wrapping my pure components in <Page>
when I wanted the layout:
return <Page>
<Stories page={page} offset={offset} stories={stories} />
</Page>
This, in my opinion, is a strength of this system. You're not constrained by artificial layout systems that are later hard to escape from.
This also applies to providers. We'll do our best to document it in the FAQ that we'll be putting together in the Wiki.
Thanks for sharing. I have a better understanding of why you went this route now. Are providers purposefully getting ignored in _document.js
in order to enforce this opinion? Otherwise, we could cater to both camps: those who prefer a global provider and those who prefer to explicitly include them on a per-page basis.
Agreed. I think we should re-open an issue to explore / document the limitations of <Document>
with regards to that
@rauchg AFAIK your example above has another cost (from what I understood of @arunoda's explanation about CommonsChunkPlugin): just because one page doesn't use some modules (like navigation in your example), it forces all other pages to have their own copy of those modules.
If I have a webapp which uses Apollo on 95% of its pages, it's indeed better if the 5% of static pages don't need to load Apollo, but it would also be better for Apollo to still load only once in the other pages.
It would be awesome if CommonsChunkPlugin could also extract the modules which aren't common to all pages but still common to several of them, would that be feasible?
@sedubois yep. We need such a functionality. But currently, it's not possible.
So I created an issue here: https://github.com/zeit/next.js/issues/738
@zachariahtimothy I integrated react-intl
with the help of redux
, if you need an example, I'll post one gladly.
@jgautheron That would be tremendous!
Here you go: https://github.com/jgautheron/nextjs2-react-intl
It still needs some refinements but it'll get you started.
I also just added i18n to my app if it helps: https://github.com/relatenow/relate
Most helpful comment
@zachariahtimothy I'm running into the same issue trying to get Apollo to play nice with Next. The fact that we can't pass down context from
_document.js
is problematic. Passing it down on every individual page isn't very dry. @nkzawa @rauchg is there any change we can make to the API so that context doesn't get wiped when wrapping<Main />
?