Skip to content
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

HTML different between build and develop - develop works ok - strange workaround #22113

Closed
funkfinger opened this issue Mar 9, 2020 · 7 comments
Labels
type: bug An issue or pull request relating to a bug in Gatsby

Comments

@funkfinger
Copy link

Please excuse if this is a duplicate, I tried to search over open issues, but didn't immediately see one that matched.

I am seeing a difference between HTML develop and build output. The bad repo creates the correct HTML in develop but bad HTML when in build. The good repo implements a workaround discovered by @stefantrinh1 and documented here- #8560 (comment)
the 'good' repo seems to creates the correct HTML in both build and develop

bad repo / depolyment:
https://github.com/funkfinger/blog/tree/bad
https://bad.jaywiggins.com

good repo / deployment:
https://github.com/funkfinger/blog/tree/good
https://good.jaywiggins.com

here is a diff between the two repos:

git diff good..bad
diff --git a/src/components/MdxPostTemplate/MdxPostTemplate.jsx b/src/components/MdxPostTemplate/MdxPostTemplate.jsx
index 83ca274..c32ae54 100644
--- a/src/components/MdxPostTemplate/MdxPostTemplate.jsx
+++ b/src/components/MdxPostTemplate/MdxPostTemplate.jsx
@@ -16,14 +16,14 @@ export const PageTemplatePure = ({
     <HeroImage img={heroImage.childImageSharp.fluid} />
   ) : null;
   return (
-    <article className={`single-post${obsolete ? ' obsolete' : ''}`}>
+    <div className={`single-post${obsolete ? ' obsolete' : ''}`}>
       {img}
       <div className="single-post-body">
         <h1>{title}</h1>
         <div className="post-date">{date}</div>
         <MDXRenderer>{body}</MDXRenderer>
       </div>
-    </article>
+    </div>
   );
 };
 
diff --git a/src/components/PostExcerpt/PostExcerpt.jsx b/src/components/PostExcerpt/PostExcerpt.jsx
index 85cb0d5..939be27 100644
--- a/src/components/PostExcerpt/PostExcerpt.jsx
+++ b/src/components/PostExcerpt/PostExcerpt.jsx
@@ -10,7 +10,7 @@ const PostExcerpt = ({ title, children, img, slug, first, obsolete }) => {
     obsolete ? ' obsolete' : ''
   }`;
   return (
-    <article className={c}>
+    <div className={c}>
       <Link to={slug}>{i}</Link>
       <div className="post-excerpt-text">
         <Link to={slug}>
@@ -21,7 +21,7 @@ const PostExcerpt = ({ title, children, img, slug, first, obsolete }) => {
           <div className="more-link">more...</div>
         </Link>
       </div>
-    </article>
+    </div>
   );
 };
 

Description

differences in outputted HTML in deployed (build) versions - left has weird <article> tag workaround...

see:

issue-b

and:

issue-a

Steps to reproduce

See good vs bad examples : the only difference is the use of the <article> tag creates correct HTML while the <div> tag produces incorrect HTML. Develop produces correct output with the <div> tag.

Expected result

Same HTML output between develop and build or with different tags (article vs div)

https://good.jaywiggins.com

Actual result

the <div class="layout"> gets replaced with <div class="post-excerpt-first first-post-in-list"> only difference is <div> tag replaced with <article> tag.

https://bad.jaywiggins.com

Environment

  System:
    OS: macOS 10.15.3
    CPU: (4) x64 Intel(R) Core(TM) i7-7Y75 CPU @ 1.30GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.16.0 - ~/.nvm/versions/node/v12.16.0/bin/node
    Yarn: 1.22.0 - ~/.yarn/bin/yarn
    npm: 6.13.4 - ~/.nvm/versions/node/v12.16.0/bin/npm
  Languages:
    Python: 2.7.16 - /Library/Frameworks/Python.framework/Versions/2.7/bin/python
  Browsers:
    Chrome: 80.0.3987.132
    Safari: 13.0.5
  npmPackages:
    gatsby: ^2.19.7 => 2.19.7 
    gatsby-image: ^2.2.42 => 2.2.42 
    gatsby-plugin-eslint: ^2.0.8 => 2.0.8 
    gatsby-plugin-manifest: ^2.2.39 => 2.2.39 
    gatsby-plugin-mdx: ^1.0.77 => 1.0.77 
    gatsby-plugin-offline: ^3.0.32 => 3.0.32 
    gatsby-plugin-react-helmet: ^3.1.21 => 3.1.21 
    gatsby-plugin-react-helmet-async: ^1.0.15 => 1.0.15 
    gatsby-plugin-sass: ^2.1.29 => 2.1.29 
    gatsby-plugin-sharp: ^2.4.5 => 2.4.5 
    gatsby-plugin-web-font-loader: ^1.0.4 => 1.0.4 
    gatsby-remark-images: ^3.1.44 => 3.1.44 
    gatsby-source-filesystem: ^2.1.46 => 2.1.46 
    gatsby-transformer-sharp: ^2.3.16 => 2.3.16 
@funkfinger funkfinger added the type: bug An issue or pull request relating to a bug in Gatsby label Mar 9, 2020
@funkfinger funkfinger changed the title CSS missing after build - develop works ok - strange workaround HTML different between build and develop - develop works ok - strange workaround Mar 9, 2020
@jlkiri
Copy link
Contributor

jlkiri commented Mar 10, 2020

Sometimes, it could be due to a mismatch between the server-rendered and client-rendered HTML. Since your classNames depend on some logic, did you make sure that logic is identical between client and server? Do you see any warnings in console like Warning: Prop `className` did not match.?

@jlkiri jlkiri added the status: awaiting author response Additional information has been requested from the author label Mar 10, 2020
@funkfinger
Copy link
Author

Thanks for the reply - gatsby-ssr.js is not in play at all. My gatsby-browser.js file is as follows:

const { createFilePath } = require('gatsby-source-filesystem');
const path = require('path');

exports.createPages = async ({ actions, graphql, reporter }) => {
  const { createPage } = actions;

  const MdxPostTemplate = path.resolve(
    'src/components/MdxPostTemplate/MdxPostTemplate.jsx'
  );

  const result = await graphql(`
    query MdxPageBuilderQuery {
      mdxPageBuilderQuery: allMdx(
        sort: { order: ASC, fields: [frontmatter___date] }
        limit: 1000
      ) {
        edges {
          node {
            fields {
              slug
            }
          }
          next {
            frontmatter {
              title
            }
            fields {
              slug
            }
          }
          previous {
            frontmatter {
              title
            }
            fields {
              slug
            }
          }
        }
      }
    }
  `);

  if (result.errors) {
    reporter.panicOnBuild('Error while running GraphQL query.');
    return;
  }

  result.data.mdxPageBuilderQuery.edges.forEach(({ node, next, previous }) => {
    createPage({
      path: node.fields ? node.fields.slug : null,
      component: MdxPostTemplate,
      context: {
        slug: node.fields.slug,
        next,
        previous,
      },
    });
  });
};

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions;
  if (node.internal.type === 'Mdx') {
    const value = createFilePath({ node, getNode });
    createNodeField({
      name: 'slug',
      node,
      value,
    });
  }
};

the code for the good and bad repos that contains the missing element are exactly the same:

    <div className="layout">
      <Seo title={t} />
      <Header />
      <main>{children}</main>
      <Footer />
    </div>

and

    <div className="layout">
      <Seo title={t} />
      <Header />
      <main>{children}</main>
      <Footer />
    </div>

in the bad version the posts are wrapped in <div> tags, but in the 'good' (workaround) version, the posts are wrapped in <article> tags.

when the posts are wrapped in <article> tags the output looks like this - please note the highlighted line - <div class="layout">

Screen Shot 2020-03-10 at 4 19 04 PM

when the posts are wrapped in <div> tags, the output looks like this - note the highlighted line is incorrect

Screen Shot 2020-03-10 at 4 17 21 PM

when the bad version is run in develop the output is correct and looks like this:

Screen Shot 2020-03-10 at 4 23 50 PM

@funkfinger
Copy link
Author

Here is the output from the build:

Jays-MacBook:blog jayw$ yarn build
yarn run v1.22.0
$ gatsby build
success open and validate gatsby-configs - 0.090s
success load plugins - 2.771s
success onPreInit - 0.009s
success delete html and css files from previous builds - 0.115s
success initialize cache - 0.039s
success copy gatsby files - 0.158s
success onPreBootstrap - 0.040s
success createSchemaCustomization - 0.039s
success source and transform nodes - 0.969s
success building schema - 0.849s
success createPages - 0.184s
success createPagesStatefully - 0.106s
success onPreExtractQueries - 0.004s
success update schema - 0.076s
success extract queries from components - 0.443s
success write out requires - 0.023s
success write out redirect data - 0.003s
success Build manifest and related icons - 1.364s
success onPostBootstrap - 1.411s
⠀
info bootstrap finished - 12.379 s
⠀
success Building production JavaScript and CSS bundles - 19.424s
success Rewriting compilation hashes - 0.007s
success run queries - 19.711s - 4/4 0.20/s
[                            ]   0.003 s 0/102 0% Building static HTML for pages
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component YouTubeVideo was not imported, exported, or provided by MDXProvider as global scope
Component YouTubeVideo was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component YouTubeVideo was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
Component Gist was not imported, exported, or provided by MDXProvider as global scope
success Building static HTML for pages - 1.866s - 102/102 54.66/s
info Done building in 34.154782359 sec
✨  Done in 35.03s.

@jlkiri jlkiri removed the status: awaiting author response Additional information has been requested from the author label Mar 11, 2020
@jlkiri
Copy link
Contributor

jlkiri commented Mar 11, 2020

OK, so apparently the problem is exactly because you wrap your page in gatsby-browser but do not do so in gatsby-ssr which leads to a mismatch during hydration. I just made your example work locally by copying everything from gatsby-browser.js to gatsby-ssr.js. You should do the same.

As stated in docs about wrapPageElement:

There is an equivalent hook in Gatsby’s SSR API. It is recommended to use both APIs together. 

https://www.gatsbyjs.org/docs/browser-apis/#wrapPageElement

@jlkiri jlkiri closed this as completed Mar 11, 2020
@funkfinger
Copy link
Author

Thanks, and you're absolutely correct. I didn't understand how gatsby-ssr.js and gatsby-browser.js were in play (and still don't) but I know now that they are more related than I believed. I would like to make a PR for updating some of the documentation on this - which states something to the order of:

If you are seeing output differences between gatsby develop and gatsby build please check that wrapPageElement and wrapRootElement are similar in both gatsby-browser.js and gatsby-ssr.js

@LRNZ09
Copy link

LRNZ09 commented Apr 13, 2020

I have had the same issue with ThemeProvider, solved by doing kind of the same thing explained here https://github.com/gatsbyjs/gatsby/tree/master/examples/using-redux

[...] you'll need to hook into two of Gatsby's extension points.

Once in wrapRootElement which runs during Gatsby's server rendering process, and once in wrapRootElement which is part of Gatsby's browser APIs.

@mckelveygreg
Copy link
Contributor

Sooo.... what if I am not use gatsby-ssr.js or gatsby-browser.js? Is there a way to double check my plugins to see if they are introducing inconsistencies?

BTW, the <article> thing totally worked.... 😨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug An issue or pull request relating to a bug in Gatsby
Projects
None yet
Development

No branches or pull requests

4 participants