-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Creating 2 layouts from same component with different context #3025
Comments
I am using last version of gatsby |
Exact same problem here. |
Problem comes from
Layout are cached along their |
As a temporary solution, I wrote down the layouts file manually. |
thanks @yachaka ,
I will try to fix it. |
@abumalick @yachaka curious why you created separate layouts - is there no way to pass the alternate language versions from the page up to the layout? I'm attempting a similar task, although my slugs are also translated. So if I were to create separate layouts then I'd end up with one for every page-language combination on the site and that seems suboptimal. |
It is not nice to pass data from the page to the layout in my opinon, it is like passing data from a child to a parent when we can pass the data in the normal way. I prefer creating a layout for each language. All pages of one language will use the same layout. Here is some code: gatsby-node.js :const _ = require(`lodash`)
const Promise = require(`bluebird`)
const path = require(`path`)
const slash = require(`slash`)
exports.createPages = ({graphql, boundActionCreators}) => {
const {createLayout, createPage} = boundActionCreators
return new Promise((resolve, reject) => {
// We get the language path
graphql(
`
{
allContentfulWebsite(limit: 1000) {
edges {
node {
languageName
languagePath
node_locale
}
}
}
}
`,
).then((languagesRes) => {
if (languagesRes.errors) {
reject(languagesRes.errors)
}
const MainLayout = path.resolve(`./src/templates/MainLayout.jsx`)
const homeTemplate = path.resolve(`./src/templates/Home.jsx`)
// we store the list of languages with their path
const languagePaths = {}
// We need languages list on all pages
// We prepare it here to be able to choose enabled languages from here
const languages = []
_.each(
languagesRes.data.allContentfulWebsite.edges,
({node: {languageName, languagePath, node_locale}}) => {
languagePaths[node_locale] = languagePath
languages.push({
languageName,
languagePath,
})
},
)
// layout for each lang
Object.keys(languagePaths).forEach((locale) => {
createLayout({
component: slash(MainLayout),
id: `main-layout-${locale}`,
context: {
languages,
locale,
},
})
})
// home pages
Object.entries(languagePaths).forEach(([locale, languagePath]) => {
createPage({
path: languagePath,
component: slash(homeTemplate),
context: {
languagePath,
languages,
locale,
},
layout: `main-layout-${locale}`,
})
})
resolve()
})
})
} MainLayout.jsximport * as React from 'react'
import 'tachyons' // eslint-disable-line
import LanguagesNav from '../components/LanguagesNav'
import './styles.css'
const MainLayout = ({children, data, layoutContext, location}) => {
const {languageChoiceLabel} = data.contentfulWebsite
const {languages} = layoutContext
const {pathname} = location
return (
<div>
<LanguagesNav
languageChoiceLabel={languageChoiceLabel}
languages={languages}
pathname={pathname}
/>
{children()}
</div>
)
}
export default MainLayout
export const pageQuery = graphql`
query mainWrapperQuery($locale: String!) {
contentfulWebsite(node_locale: {eq: $locale}) {
languageChoiceLabel
}
}
` For the translated slugs I don't know how you have to do it though. |
Thanks @abumalick, I ended up using the English (base) slugs for the translated articles. Seems it's the way Gatsby is structured. In Jekyll you don't specifically pass variables back up the layout, but the layout will execute one time for each page and so it can expect variables as if it were the page itself. In Gatsby it seems to render the template once, then repeat that for each page. |
This is a ugly fix for this ref: gatsbyjs/gatsby#3025 fixes #22
Hello,
I am developing a multilingual website and need to pass the current language to
the layout. For this I used
createLayout
:The problem is that when I log
props.layoutContext.locale
inside myMainLayout
, I always getfr-FR
(on the arabic page and the french page)While investigating, I could make it work when I duplicate my
template/MainLayout file, and use one file for each language (this is very very
ugly):
After that I tried to debug it in gatsby, cloned the repo, and configured
redux-devtools.
While examining the store, I noticed that the layouts are created correctly with
the good context for each layout, and that pages are also created correctly,
with their corresponding layout id.
I am a bit stuck because redux-tools resets its history while building, so I
cannot look at the actions creating the pages to try and debug more.
Can you give me any indication to how to investigate further ?
The text was updated successfully, but these errors were encountered: