Recently IN learning Gridsome, along with the video tutorial to implement a case and successful deployment, here to record the learning process, so as not to encounter any pit later come back to look over. Strapi project source code Gridsome project source code

What is Gridsome?

  • A free, open source static web site generator based on vue.js technology stack
  • Official website: Gridsome.org/
  • Making: github.com/gridsome/gr…

Static web site builder?

  • Is a tool for generating static HTML files and related resources using a series of configurations, templates, and data
  • Also called pre-render
  • You don’t need a server like PHP to review a sad website
  • It only needs to be placed on a Web Server or CDN that supports static resources

Benefits of static websites

  • To save money, you don’t need a professional server, just space to host static files
  • Fast transfer of content without back-end server processing
  • Security Is more secure without the execution of back-end programs

Common static web site generator

  • Jekyll(Ruby)
  • Hexo(Node)
  • Hugo(Golang)
  • Gatsby(Node/React)
  • Gridsome(Node/Vue)
  • In addition, Next. Js and nuxt.js can also generate static websites, but they are more commonly thought of as SSR frameworks.

This static site generator, also known as JAMStack, is essentially a fat front end that calls various apis to achieve more functionality, but is also a model of front and back ends that are different, even from multiple vendors.

Static application scenarios

  • Not suitable for applications with a large number of routed pages
    • If you have hundreds or thousands of routed pages on your site, pre-rendering can be very slow. Of course, if you only need to do one update per update, it might take some time. Most people don’t end up with thousands of statically routed pages, just in case.
  • Not suitable for applications with lots of dynamic content
    • If the render path contains content that is specific to the user viewing its content or other dynamic resources, make sure you have placeholder components that can be displayed until the dynamic content is loaded to the client, otherwise it can be weird.

Create a Gridsome project

C++ files are included in sharp, and the libvips package in sharp is too large to be successfully installed in China. Therefore, it is best to configure the domestic address of these two packages.

npm config set sharp_binary_host "https://npm.taobao.org/mirrors/sharp"
npm config set sharp_libvips_binary_host "https://npm.taobao.org/mirrors/sharp-libvips"
Copy the code

Then you need to compile the c++ file in sharp and download the node-gyp package, which requires a python environment.

npm install -g node-gyp
Copy the code

From there, you can create your project in Gridsome

gridsome create my-gridsome-site
Copy the code

Dependencies are automatically installed at this point, and we can interrupt ourselves to reinstall node_modules. Then run NPM Run Develop to start the development mode of the project to display the effect of the page, where the two. Vue files under Pages correspond to the corresponding routes. Running NPM Run Build packages the entire project and generates static, pre-rendered HTML files.

Gridsome basis – Pages

A new page

There are two ways to create a page. 1. Use the file system to create a. Vue file in the SRC directory. Gridsome will automatically generate the routing configuration and convert it to lowercase. 2. You can also use the corresponding API to create components. In the gridsome.server.js file, call the createPage method to generate the route.

module.exports = function (api) {
    api.loadSource(({ addCollection }) => {
        // Use the Data Store API here: https://gridsome.org/docs/data-store-api/
    })

    api.createPages(({ createPage }) => {
        // Use the Pages API here: https://gridsome.org/docs/pages-api/
        createPage({
            path: '/my-page',
            component: './src/templates/MyPage.vue'
        })
    })
}
Copy the code

Dynamic routing

Dynamic routes can be created in two ways. 1. Dynamic routing based on files:

src/pages/user/[id].vue => /user/:id
src/pages/user/[id]/settings.vue => /user/_id/settings
Copy the code

2. Create the way to call the API. Call from gridsome.server.js:

api.createPages(({ createPage }) => {
    createPage({
        path: '/user/:id(\\d+)',
        component: './src/templates/User.vue'
    })
})
Copy the code

Generate routing rewrite rules

Because the /user/:id route will eventually produce a file with a path of /user/ id.html that a normal static Web server would not process, it is up to us to rewrite the rules for dynamic routing.

Copy the code

A collection of

If we have an interface that returns an array, each item in the array is an object, and displays the entire array on a page, it’s easy.

[
    {
        userid: '1',
        id: 1,
        title: 'title',
        body: 'body'
    }
]
Copy the code

However, such dynamically acquired data is displayed in the page, which is dynamically rendered by the client, rather than a static page effect generated by pre-rendering. In this case, the collection is needed. The loadSource method is also called in gridsome.server.js to add the collection, with the data calling jsonPlaceholder’s test interface.

const axios = require('axios')
module.exports = function (api) {
    api.loadSource(async ({ addCollection }) => {
        const collection = addCollection('Post')
        const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
            for (const item of data) {
                collection.addNode({
                    id: item.id,
                    title: item.title,
                    content: item.body
                })
            }
        })
    }
}
Copy the code

Each collection adds two new fields to the GraphQL Schema: POST and allPost. Post is to get a single node by ID, allPost is to get the entire node. After starting the development service, there is a GraphQL explorer where you can query the data in the collection. Of course, you still need to use the tag in the page to fetch the data in the GraphQL.

<page-query>
query {
    post: allPost{
        edges {
            node {
              id
              title
            }
        }
    }
}
</page-query>
Copy the code

At this point, the data POST from the GraphQL is written to the $page that calculates the property and can be used directly in the page:

<template>
    <Layout>
        <div>
            <h1>Post2 Page</h1>
            <ul>
                <li v-for="edge in $page.post.edges"
                    :key="edge.id">
                    <g-link :to="edge.node.path">{{edge.node.title}}</g-link>
                </li>
            </ul>
        </div>
    </Layout>
</template>
<page-query>
query {
    post: allPost {
        edges {
            node {
                id
                title
                path
            }
        }
    }
}
</page-query>
<script>
export default {
    name: 'Post2Page'
}
</script>
Copy the code

You can also query data based on a given parameter.

<page-query>
query ($id: ID!) {
    post (id: $id) {
        id
        title
        content
    }
}
</page-query>
Copy the code

In GraphQL, variables start with the query parameter id: id! Indicates that the parameter is of type ID and is not null. After the data is retrieved, it can be used using $page.

<div>{{ $page.post.content}}</div>
Copy the code

Gridsome case

We’ll use the Gridsome Create blog-with-Gridsome command to create and start the project. Then we’ll use the open source template on Github, preferably forking it to our own account to prevent the template file from being deleted or otherwise modified by the author.

Processing of templates

Once the template is downloaded, you must add the resources referenced in it to the Gridsome project, including the bootstrap and @fortawesome/ Fontawesome -free packages, as well as the two font files to be imported into the CSS and imported into main.js. Create a SRC /assets/ CSS /index.css file and add font resources to the file:

@ import url (" https://fonts.googleapis.com/css?family=Lora:400, 700400 italic, 700 itali "); @import Url, "https://fonts.googleapis.com/css?family=Open+Sans:300italic, 400 italic, 600 italic, 700 italic, italic, 800 400300600 0800 ")Copy the code

In the template, the header navigation and the tail of each page are essentially the same and can be placed in the default layout component, while the content in the middle can be placed in separate components. So the final Layout component should be:

<template>
	<div class="layout">
    	<nav>.</nav>
        <! -- Subcomponent exit -->
        <slot />
        <footer>.</footer>
    </div>
</template>
Copy the code

Once the template is complete, we will use gridsome to build a purely static blog site.

Local MD file management article content

Of course, the most important function of a blog is to present articles

strapi

Strapi itself is an advanced content management framework that makes it easy to generate the apis we need. Create a local strAPI application:

npx create-strapi-app my-project --quickstart
Copy the code

After that, the strAPI registration page will be automatically opened, and it is good to register directly. After the registration is completed, the system will enter the background.

Then click Create a new Content Type in the Content Type Generator to create a collection, and with the collection, we can manage our data. After data is added, do not forget to set the user’s permission. Set the public permission type count find Findone permission. When selecting the permission, the corresponding interface name will appear on the right.

Note that the need for science online, otherwise not savedCopy the code

After setting up, you can test the data of the corresponding interface.

http://localhost:1337/posts/count
Copy the code

If you want to fetch data using graphQL in StrAPI, you need to do the following:

yarn strapi install graphql
Copy the code

After installation, run NPM Run Develop to start

Note that this is a my-project project, not a gridsome-created project!Copy the code

Start after successful, open http://localhost:1337/graphql graphql can be used to query data in strapi.

About data prefetch

To integrate strAPI into gridsome, you need to use a plug-in for @Gridsome/source-strAPI.

// Notice that you are in a Gridsome project. npm install @gridsome/source-strapiCopy the code

Then add the following code to the plugins in the gridsome.config.js configuration file:

{
    use: '@gridsome/source-strapi',
        options: {
        apiURL: 'http://localhost:1337',
            queryLimit: 1000,
                contentTypes: ['post'],
                    loginData: {
            identifier: '',
                password: ''
        }
    }
}
Copy the code

Finally, restart the NPM Run Develop application to make the configuration change take effect and get the data from strAPI

Note that both projects are started at the same time, because the gridsome project queries the data from StrAPI, while the StrAPI data is retrieved from the strAPI backend system through the My-Project project. If you add data to strAPI in the background, you won't be able to find it in Gridsome, because pre-rendering takes the data in advance and renders it to the page. Since pre-rendering takes place after pre-rendering, the pre-rendering process can't get the new data. To solve this problem, Just restart the Gridsome service.Copy the code

On the page

Gridsome provides the @Paginate API for paging. You can customize the number of pages and items per page.

query ($page: Int) {
    posts: allStrapiPost (perPage: 1, page: $page) @paginate {
        edges {
            node {
                id
                title
                created_at
                createds {
                    id
                    firstname
                    lastname
                }
                tags {
                    id
                    title
                }
            }
        }
    }
}
Copy the code

The Gridsome also provides the paging component Pager, which needs to be registered and used as a normal component, as well as adding a query statement to the page-query:

query ($page: Int) { posts: allStrapiPost (perPage: 1, page: $page) @paginate { pageInfo { totalPages currentPage } ... }}Copy the code

The pager component needs to add a property to the page to work properly. This component has no added style and can be configured according to our needs. As for the page, there is no more detail here.

<pager :info="$page.posts.pageInfo"></pager>
Copy the code

About the deployment

Gridsome projects, the blog application itself, can be deployed on any web service that supports static files, while StrAPI applications require node environments. Since the Gridsome project needs to request StrAPI’s services to get pre-rendered data at startup, the StrAPI application is deployed first.

By default, STRAPI uses SQLite to store data. You can also use other databases such as mysql mongodb. There are corresponding configuration items on the official website.

To use mysql, you must first have mysql on the server, and then modify the strAPI project configuration file config\database.js. Modify the configuration file as follows:

module.exports = ({ env }) => ({
    defaultConnection: 'default',
    connections: {
        default: {
            connector: 'bookshelf',
            settings: {
                client: 'mysql',
                host: env('DATABASE_HOST', 'localhost'),
                port: env.int('DATABASE_PORT', 3306),
                database: env('DATABASE_NAME', 'blog'),
                username: env('DATABASE_USERNAME', 'root'),
                password: env('DATABASE_PASSWORD', ''),
            },
            options: {},
        },
    },
});
Copy the code

Mysql and Strapi are on the same server. If they are on different servers, the address of other servers should be written here. Secondly, there should be a database named blog, otherwise the corresponding database cannot be found during deployment.

The deployment process is also very simple, directly clone the source code on the cloud server, and then run NPM install NPM run build and other commands, direct packaging is good, but this way has a disadvantage, is the current connection is broken, the service will also hang, so here use PM2 to execute the NPM command.

Gridsome uses Vercel to build and deploy. Vercel supports deploy hooks that automatically trigger builds after strap adds data. However, there are disadvantages to this method. A small amount of data is reasonable, but a large amount of data will trigger multiple builds, which can only be said to be mutually beneficial.