Gatsby: Dynamically Create Pages without Builds

Created on 21 Feb 2019  路  8Comments  路  Source: gatsbyjs/gatsby

I was looking at the screencast that @DSchau did (great job btw) about creating dynamic websites with Gatsby. I'm looking to create a dynamic site myself and am wondering if Gatsby can fit the bill.

It looks like there is an awesome support for creating a static page and then populating that page with content that exists both at build time and then with additional content retrieved dynamically. For example, if I were creating website like hacker news, I could generate the frontpage at build-time, and then when users visited the website, I could request additional links from the server and intersperse those with that statically built links.

What if I want to create additional pages after the build process had finished? What if I want to be able to have users visit the url /links/5005, even though link 5005 never existed at built time? Is there support to do something like this in Gatsby? I know that I can just rebuild (though this might take a while), or I could have this content available from a serverside URL, but does Gatsby provide any other options?

Thank you for the help!

Most helpful comment

@nadrane hey thanks!

I think you're referring to client-only routes, which is exactly what the gatsby-mail application does! (One note: gatsby-plugin-create-client-paths is helpful here!)

You can think of it like a glob/wildcard pattern, e.g. for your use case you could define /links/:id as your client-only path(s), and you'd "hydrate" the data client side upon request by fetching the data, e.g. with GraphQL, REST API call, etc.

Upon navigating to /links/5005 you'd have a component at src/pages/links/index.js that will need some way to fetch data, e.g. a REST call or GraphQL query upon mounting. If you may already have the data, you can

I _think_ this answers your question, but happy to assist further if I can help!

All 8 comments

@nadrane hey thanks!

I think you're referring to client-only routes, which is exactly what the gatsby-mail application does! (One note: gatsby-plugin-create-client-paths is helpful here!)

You can think of it like a glob/wildcard pattern, e.g. for your use case you could define /links/:id as your client-only path(s), and you'd "hydrate" the data client side upon request by fetching the data, e.g. with GraphQL, REST API call, etc.

Upon navigating to /links/5005 you'd have a component at src/pages/links/index.js that will need some way to fetch data, e.g. a REST call or GraphQL query upon mounting. If you may already have the data, you can

I _think_ this answers your question, but happy to assist further if I can help!

I see, that makes complete sense to me conceptually. Thank you for the quick response!

So, I imagine (and think I read elsewhere) that these client-only routes would not be accessible from the URL bar, right? The server just wouldn't know the page exists. I could only link to these client-only routes from within my application. This should be fine for my use case, but I just want to confirm my understanding

What exactly do you mean by "the server" here?

They're fully functional routes, e.g. if the user goes to https://your-app.com/links/5005 that URL will _work_ (presuming you wire it up correctly!).

That's super cool. I wasn't expecting that.
By server, I just mean whatever static file server is hosting my build. There's no way the client-only route can have an index.html in the build.

So effectively you're saying the route is generated through javascript. That makes perfect sense to me. thank you @DSchau !

Excellent! Glad to have helped :)

Going to close this out, but please feel free to continue the discussion if you have any other questions!

Thanks for the question, the kind words, and using Gatsby. Appreciate it! 馃挏

Hello guys,

Can you help me please?

I think it's maybe the same problem: https://github.com/gatsbyjs/gatsby/issues/12587

but I don't understand how do solve that.

Sorry to open up but this is the best thread I've found for my query!

Clientside routing looks like a great idea for me to not have to generate 10k+ pages if I want to do something like /link-out/:id where :id refers to the id of a link that sits inside the Gatsby data source.

Is there a way I can query what's already inside Gatsby from a client only route? StaticQuery doesn't accept variables and I'm not confident in my understanding of gatsby-node.js enough to work out where to grab that :id parameter and push it as the page context.

There are many solutions that involve axios / fetch to query from third party APIs - is it really as simple as setting the url to /__graphql?

edit: https://github.com/gatsbyjs/gatsby/issues/10482
Looks as though the answer is 'No for now'

``exports.onCreatePage = async ({ page, actions }) => { const { createPage } = actions // page.matchPath is a special key that's used for matching pages // only on the client. if (page.path.match(/^\/link-out/)) { page.matchPath =/link-out/*`
// Update the page.. <-- This happens at build time.. Am I right in thinking I can't I grab the link-out/:id here and do some logic to pass on a page context? page.context = ?
createPage(page)

}
}```

@nadrane hey thanks!

I think you're referring to client-only routes, which is exactly what the gatsby-mail application does! (One note: gatsby-plugin-create-client-paths is helpful here!)

You can think of it like a glob/wildcard pattern, e.g. for your use case you could define /links/:id as your client-only path(s), and you'd "hydrate" the data client side upon request by fetching the data, e.g. with GraphQL, REST API call, etc.

Upon navigating to /links/5005 you'd have a component at src/pages/links/index.js that will need some way to fetch data, e.g. a REST call or GraphQL query upon mounting. If you may already have the data, you can

I _think_ this answers your question, but happy to assist further if I can help!

How can I get the 5005 url param in this case inside the component?

Regards

Was this page helpful?
0 / 5 - 0 ratings