wiziple / gatsby-plugin-intl

Gatsby plugin that turns your website into an internationalization-framework out of the box.
http://gatsby-starter-default-intl.netlify.com
325 stars 178 forks source link

[bug]: gatsby-plugin-intl and gatsby-plugin-remote-trailing-slashes do not play together nicely #18

Open kwiechmann opened 5 years ago

kwiechmann commented 5 years ago

Description

Both slash stripper and internationalization plugins need to mash up so as to meet both common SEO and multilingual requirements. The ordering of the plugins in this case is important. If trailing slashes is first the browser URL is more correct but SEO is potentially dinged.

For best results, internationalization should follow stripper. Did not realize that the plugins were order sensitive in gatsby-config.js. As long as the URL has at least two levels, this is fairly close but may still have the trailing slash.

Steps to reproduce

  1. Begin with the "my-blog-starter"
gatsby new my-blog-starter https://github.com/gatsbyjs/gatsby-starter-blog
cd my-blog-starter
  1. Install the "gatsby-plugin-remote-trailing-slashes"
npm install --require gatsby-plugin-remove-trailing-slashes
  1. Update gatsby-config.js
    'gatsby-plugin-remove-trailing-slashes',
{
      resolve: `gatsby-plugin-intl`,
      options: {
        // language JSON resource path
        path: `${__dirname}/src/intl`,
        // supported language
        languages: [`en`, `ko`, `de`],
        // language file path
        defaultLanguage: `en`,
        // option to redirect to `/en` when connecting `/`
        redirect: true,
      },
  1. Add translation files de.json, en.json, and ko.json to src/intl directory taking from these file at the following URL:
https://github.com/wiziple/gatsby-plugin-intl/tree/master/examples/gatsby-starter-default-intl/src/intl.
  1. Update the main project's index.js file as follows to include international text:
import React from "react"
// TKTKTK
// import { Link, graphql } from "gatsby"
import { graphql } from "gatsby"
import { FormattedMessage, Link, injectIntl } from "gatsby-plugin-intl"

import Bio from "../components/bio"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { rhythm } from "../utils/typography"

class BlogIndex extends React.Component {
  render() {
    const { data } = this.props
    const siteTitle = data.site.siteMetadata.title
    const posts = data.allMarkdownRemark.edges

    // TKTKTK
    const intl = this.props.intl
    const intlTitle = intl.formatMessage({ id: "welcome" });

    return (
      <Layout location={this.props.location} title={siteTitle}>
        <SEO title="All posts" />

        <h1>{intlTitle}</h1>
        <h1><FormattedMessage id="title" /></h1>
        <h1><FormattedMessage id="hello" /></h1>

        <Bio />
        {posts.map(({ node }) => {
          const title = node.frontmatter.title || node.fields.slug
          return (
            <div key={node.fields.slug}>
              <h3
                style={{
                  marginBottom: rhythm(1 / 4),
                }}
              >
                <Link style={{ boxShadow: `none` }} to={node.fields.slug}>
                  {title}
                </Link>
              </h3>
              <small>{node.frontmatter.date}</small>
              <p
                dangerouslySetInnerHTML={{
                  __html: node.frontmatter.description || node.excerpt,
                }}
              />
            </div>
          )
        })}
      </Layout>
    )
  }
}

// TKTKTK
// export default BlogIndex
export default injectIntl(BlogIndex)

export const pageQuery = graphql`
  query {
    site {
      siteMetadata {
        title
      }
    }
    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
      edges {
        node {
          excerpt
          fields {
            slug
          }
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            title
            description
          }
        }
      }
    }
  }
`
  1. Update the main project's blog-post.js file as follows to include international text:
    
    import React from "react"
    // TKTKTK
    // import { Link, graphql } from "gatsby"
    import { graphql } from "gatsby"
    import { FormattedMessage, Link, injectIntl } from "gatsby-plugin-intl"

import Bio from "../components/bio" import Layout from "../components/layout" import SEO from "../components/seo" import { rhythm, scale } from "../utils/typography"

class BlogPostTemplate extends React.Component { render() { const post = this.props.data.markdownRemark const siteTitle = this.props.data.site.siteMetadata.title const { previous, next } = this.props.pageContext

// TKTKTK
const intl = this.props.intl
const intlTitle = intl.formatMessage({ id: "welcome" });
// const intlTitle = 'fubar'

return (
  <Layout location={this.props.location} title={siteTitle}>
    <SEO
      title={post.frontmatter.title}
      description={post.frontmatter.description || post.excerpt}
    />

    <h1>{intlTitle}</h1>
    <h1><FormattedMessage id="title" /></h1>
    <h1><FormattedMessage id="hello" /></h1>

    <h1>{post.frontmatter.title}</h1>
    <p
      style={{
        ...scale(-1 / 5),
        display: `block`,
        marginBottom: rhythm(1),
        marginTop: rhythm(-1),
      }}
    >
      {post.frontmatter.date}
    </p>
    <div dangerouslySetInnerHTML={{ __html: post.html }} />
    <hr
      style={{
        marginBottom: rhythm(1),
      }}
    />
    <Bio />

    <ul
      style={{
        display: `flex`,
        flexWrap: `wrap`,
        justifyContent: `space-between`,
        listStyle: `none`,
        padding: 0,
      }}
    >
      <li>
        {previous && (
          <Link to={previous.fields.slug} rel="prev">
            ← {previous.frontmatter.title}
          </Link>
        )}
      </li>
      <li>
        {next && (
          <Link to={next.fields.slug} rel="next">
            {next.frontmatter.title} →
          </Link>
        )}
      </li>
    </ul>
  </Layout>
)

} }

// TKTKTK // export default BlogPostTemplate export default injectIntl(BlogPostTemplate)

export const pageQuery = graphql query BlogPostBySlug($slug: String!) { site { siteMetadata { title author } } markdownRemark(fields: { slug: { eq: $slug } }) { id excerpt(pruneLength: 160) html frontmatter { title date(formatString: "MMMM DD, YYYY") description } } }


7. From the main project directory, execute the following command to start Gatsby:

clear && rm -rf .cache public && gatsby develop



### Expected and Actual result

When order in gatsby-config.js:

1. gatsby-plugin-intl
2. gatsby-plugin-remove-trailing-slashes

http://localhost ==> 
http://localhost/en/ ==> 
Actual: http://localhost/en/en/ with English text
Expected: http://localhost/en with English text

http://localhost/ ==> 
http://localhost/en/ ==> 
Actual: http://localhost/en/en/ with English text
Expected: http://localhost/en with English text

http://localhost/de ==>
Actual: http://localhost/en/de with English text
Expected: http://localhost/de with German text

http://localhost/de/ ==>
Actual: http://localhost/en/de/ with English text
Expected: http://localhost/de with German text

http://localhost/my-second-post ==>
Actual: http://localhost/en/en/my-second-post with English text
Expected: http://localhost/en/my-second-post English text

http://localhost/my-second-post/ ==>
Actual: http://localhost/en/en/my-second-post/ with English text
Expected: http://localhost/en/my-second-post with English text

http://localhost/de/my-second-post ==>
Actual: http://localhost/en/de/my-second-post with English text
Expected: http://localhost/de/my-second-post with German text

http://localhost/de/my-second-post/ ==>
Actual: http://localhost/en/de/my-second-post/ with English text
Expected: http://localhost/de/my-second-post with German text

When order in gatsby-config.js:

1. gatsby-plugin-remove-trailing-slashes
2. gatsby-plugin-intl

http://localhost ==> 
http://localhost/en/ ==> 
Actual: http://localhost/en/en/ with English text
Expected: http://localhost/en with English text

http://localhost/ ==> 
http://localhost/en/ ==> 
Actual: http://localhost/en/en/ with English text
Expected: http://localhost/en with English text

http://localhost/de ==>
Actual: http://localhost/en/de with English text
Expected: http://localhost/de with German text

http://localhost/de/ ==>
Actual: http://localhost/en/de/ with English text
Expected: http://localhost/de with German text

http://localhost/my-second-post ==>
Actual: http://localhost/en/my-second-post with English text
Expected: Successful URL with English text

http://localhost/my-second-post/ ==>
Actual: http://localhost/en/my-second-post/ with English text
Expected: http://localhost/en/my-second-post with English text

http://localhost/de/my-second-post ==>
Actual: http://localhost/de/my-second-post with German text
Expected: Successful URL with German text

http://localhost/de/my-second-post/ ==>
Actual: http://localhost/de/my-second-post/ with German text
Expected: http://localhost/de/my-second-post with German text

Only gatsby-plugin-intl enabled in gatsby-config.js:

http://localhost ==> 
Actual: http://localhost/en/ with English text
Expected: Successful URL with English text

http://localhost/ ==> 
Actual: http://localhost/en/ with English text
Expected: Successful URL with English text

http://localhost/de ==>
Actual: http://localhost/de with German text
Expected: Successful URL with German text

http://localhost/de/ ==>
Actual: http://localhost/de/ with German text
Expected: Successful URL with German text

http://localhost/my-second-post ==>
Actual: http://localhost/en/my-second-post with English text
Expected: Successful URL with English text

http://localhost/my-second-post/ ==>
Actual: http://localhost/en/my-second-post/ with English text
Expected: Successful URL with English text

http://localhost/de/my-second-post ==>
Actual: http://localhost/de/my-second-post with German text
Expected: Successful URL with German text

http://localhost/de/my-second-post/ ==>
Actual: http://localhost/de/my-second-post/ with German text
Expected: Successful URL with German text

### Errata
Maybe these two plugins would benefit from being combined together. The addition of the stripping slashes feature into international would seem pretty straight forward and might result in better performance.

~~Tomorrow, I plan to run the tests with just international. I will update with my findings.~~ Updated.

### Environment

  System:
    OS: macOS 10.14.5
    CPU: (8) x64 Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz
    Shell: 5.0.2 - /usr/local/bin/bash
  Binaries:
    Node: 10.15.2 - /usr/local/bin/node
    Yarn: 1.15.2 - ~/.yarn/bin/yarn
    npm: 6.9.0 - /usr/local/bin/npm
  Languages:
    Python: 2.7.10 - /usr/bin/python
  Browsers:
    Chrome: 74.0.3729.169
    Safari: 12.1.1
  npmPackages:
    gatsby: ^2.7.5 => 2.7.5 
    gatsby-image: ^2.1.2 => 2.1.2 
    gatsby-plugin-feed: ^2.2.1 => 2.2.1 
    gatsby-plugin-google-analytics: ^2.0.20 => 2.0.20 
    gatsby-plugin-intl: ^0.1.7 => 0.1.7 
    gatsby-plugin-manifest: ^2.1.1 => 2.1.1 
    gatsby-plugin-offline: ^2.1.1 => 2.1.1 
    gatsby-plugin-react-helmet: ^3.0.12 => 3.0.12 
    gatsby-plugin-remove-trailing-slashes: ^2.0.11 => 2.0.11 
    gatsby-plugin-sharp: ^2.1.2 => 2.1.2 
    gatsby-plugin-typography: ^2.2.13 => 2.2.13 
    gatsby-remark-copy-linked-files: ^2.0.13 => 2.0.13 
    gatsby-remark-images: ^3.0.14 => 3.0.14 
    gatsby-remark-prismjs: ^3.2.9 => 3.2.9 
    gatsby-remark-responsive-iframe: ^2.1.1 => 2.1.1 
    gatsby-remark-smartypants: ^2.0.9 => 2.0.9 
    gatsby-source-filesystem: ^2.0.37 => 2.0.37 
    gatsby-transformer-remark: ^2.3.12 => 2.3.12 
    gatsby-transformer-sharp: ^2.1.20 => 2.1.20 
  npmGlobalPackages:
    gatsby-cli: 2.6.3

AdvThanksance!!!
claudyanovery commented 3 years ago

No updates about this bug?