-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
💡 RFC: File-Based Routing /w Dynamic Paths #1004
Comments
Added label to discuss at our next RFC meeting! @snowpackjs/contributors-l2 @snowpackjs/contributors-core I'd love to get consensus on the full design / implementation if possible with the intention of merging the PR if consensus is reached. If you expect to have feedback on this proposal please take a look ahead of time and share any thoughts here! |
Very much looking forward to when Or, if that’s not possible, the return of components in Markdown. Or, better yet, both. 😄 🙏 |
I think you can do something similar with regular imports? https://docs.astro.build/guides/imports/ Would const data = import.meta.globEager(**/*.json); be valid? |
Main interest is in dealing with existing Markdown files with imported images that, in other SSGs, I use shortcodes to handle responsiveness and such. With |
Would also love to see documentation on exposed “next page,” “this page,” and “previous page” vars from this method (if they exist). To clarify, I refer not to such vars for a paginated list — already documented in the new API page — but, rather, for individual pages in a sorted list. That way, for example, each blog post in a sorted list can have “previous post” and “next post” vars (URL, data from front matter, etc.) to which it can link. If those are already exposed in |
|
I thought those are for only pagination and work only with pages with the |
ah, so you want to access the pagination info from the individual post pages, that makes sense, there's a similar setup in Hugo |
Exactly. On my current site (https://www.brycewray.com), each post has a section at the bottom which uses the Eleventy collection to get previous post and next post. Now, mind you, that part wasn't always easy 😄 in Eleventy: For example, in my current Eleventy site, I have this at the bottom of my per-post template (this is Nunjucks) {% if page.url != "/about/" %}
<div class="w-full px-8 md:px-0 bg-black dark:bg-blue-900 align-middle mt-10 mb-10">
<h3 class="text-center text-3xl tracking-normal mb-2 pt-2"><a href="/posts" class="border-transparent text-blue-100 hover:text-blue-200 hover:border-blue-200">Other posts</a></h3>
{% if nextPost.url %}
<p class="font-sans text-center mt-2 mb-2 text-xl lg:text-2xl text-white leading-tight tracking-tight">
<strong>Next</strong>:
<a class="border-transparent text-blue-100 hover:text-blue-200 hover:border-blue-200" href="{{ nextPost.url }}">{{ nextPost.data.title }}</a>
</p>
{% endif %}
{% if prevPost.url %}
<p class="font-sans text-center pb-4 mt-2 mb-0 text-xl lg:text-2xl text-white leading-tight tracking-tight">
<strong>Previous</strong>:
<a class="border-transparent text-blue-100 hover:text-blue-200 hover:border-blue-200" href="{{ prevPost.url }}">{{ prevPost.data.title }}</a>
</p>
{% else %}
<p class="p-0 -mt-2 leading-none"> </p>
{% endif %}
</div>
{% endif %}
|
Nice! I really like that. You can do the same in Astro using |
Thanks @FredKSchott! (Although I thought the |
@brycewray sorry, not sure I follow your last comment. The |
@FredKSchott all I know is that the following, in ---
export async function getStaticPaths({ paginate }) {
const allPosts = Astro.fetchContent('../posts/**/*.md')
const sortedPosts = allPosts.sort(
(a, b) => new Date(b.date) - new Date(a.date)
);
// Return a paginated collection of paths for all posts
return paginate(sortedPosts, { pageSize: 5 })
}
// The page prop has everything that you need to render a single page in the collection.
const { page } = Astro.props
import Layout from 'layouts/Base.astro'
import { zonedTimeToUtc, utcToZonedTime, format } from "date-fns"
const dateFormat = (item) => format((Date.parse(item)), 'MMMM d, yyyy')
---
<!DOCTYPE html>
<Layout
title="Posts list"
>
<main class="pt-12">
<div class="sm:w-5/6 md:w-4/5 lg:2/3 xl:w-7/12 mt-10 mr-auto ml-auto px-6 lg:px-16">
<article class="article">
<h1>Testing the new routing stuff</h1>
<p>This is just text.</p>
<p>This is page number {page.page.current}.</p>
<p>The total number of pages is {page.page.last}.</p>
<p>Page URL = {page.url.current}</p>
<p>{page.start + 1}–{page.end + 1} of {page.total}</p>
{page.data.map((post =>
<>
<p><a href={post.url}>{post.title}</a></p>
<p>Date: {dateFormat(post.date)}</p>
</>
))}
</article>
<p class="text-center">
{page.url.prev
? `<a href=${page.url.prev}>Previous</a>`
: `<span class="text-gray-500">Previous</span>`
}
•
{page.url.next
? `<a href=${page.url.next}>Next</a>`
: `<span class="text-gray-500">Next</span>`
}
</p>
</div>
</main>
</Layout> ...but now it produces the following when I try to view [access] /posts/
[executing astro] TypeError: Cannot read property 'current' of undefined
at Object.__render (/_astro/src/pages/posts/[...page].astro.js:80:906)
at Object.__renderPage (/_astro/src/pages/posts/[...page].astro.js:114:46)
at load (file:///Users/thewrays/astro-site/node_modules/astro/dist/runtime.js:110:34)
at async Server.<anonymous> (file:///Users/thewrays/astro-site/node_modules/astro/dist/dev.js:21:20)
[access] /500 It also errors out during builds, so it's not just a dev-mode issue: [build] Unable to render src/pages/posts/[...page].astro
TypeError: Cannot read property 'current' of undefined
at file:///Users/thewrays/astro-site/src/pages/posts/[...page].astro
at file:///Users/thewrays/astro-site/src/pages/posts/[...page].astro
at Object.__renderPage (file:///Users/thewrays/astro-site/src/pages/posts/[...page].astro
at load (file:///Users/thewrays/astro-site/node_modules/astro/dist/runtime.js:110:34)
at async buildStaticPage (file:///Users/thewrays/astro-site/node_modules/astro/dist/build/page.js:25:18)
at async Promise.all (index 0)
at async file:///Users/thewrays/astro-site/node_modules/astro/dist/build.js:75:9
at async Promise.all (index 9)
at async build (file:///Users/thewrays/astro-site/node_modules/astro/dist/build.js:74:7)
at async buildAndExit (file:///Users/thewrays/astro-site/node_modules/astro/dist/cli.js:10:15)
[build] ✕ building pages failed! Still same repo — https://github.com/brycewray/astro-site — but, as noted, can't re-build the demo on Vercel right now, so what you'll see in https://astro-site.vercel.app/posts/ reflects what I got before. |
Ah right, the interface has changed a bit. we can add a warning if you try to access |
Thanks! Will have to wait a while before I can try it, however -- my daughter is in the process of delivering our second grandchild. 😃 |
CONGRATULATIONS!!! That's amazing!!! |
Would Also, it seems that any change that affects the value returned by |
Yea, I wonder why Next.js and SvelteKit haven't implemented this. Does anyone know? I'd be +1 for adding this as a follow-up PR if it makes sense. Because
Yup, this regression is caused by the Snowpack bug linked in OP, fixed and ready to go out. |
On second thought, |
Background
Motivation
route
,paths
, andprops
) adds friction, since it really only works if all are defined.route
in config feels especially odd, because the file path itself is meant to be the route.Now that Astro has launched publicly and is moving closer to a v1.0 beta, our biggest reasons to avoid building more advanced file-based routing are no longer relevant. This proposal is to add true file-based routing with dynamic path support, ala Next.js or SvelteKit.
Non-Goals
This RFC does not add dynamic, server-side routes to Astro. Astro is still a 100% static site builder. However, this RFC does solve for one of the biggest missing features in Astro that was blocking dynamic routing, so you can consider this as one step closer to unblocking dynamic routes in Astro.
Proposal
[x]
and[...x]
filenames inside ofsrc/pages
to represent URL params in your routes. ReplacecreateCollection
with a simplergetStaticPaths
function to statically generate pages.Filename Syntax
pages/blog/[slug].astro
→/blog/:slug
(/blog/hello-world
,/blog/post-2
, etc.)pages/[username]/settings.astro
→ (/fred/settings
,/drew/settings
, etc.)pages/[lang]-[version]/info.astro
→ (/en-v1/info
,/fr-v2/info
, etc.)pages/post/[...slug].astro
→ (/post/a
,/post/a/b
,/post/a/b/c
, etc.)getStaticPaths()
Design
Proof of Concept PR with design & implementation details: #1010
Open Questions
/a/b/c
matchingsrc/pages/[...id].astro
could return a path object of{params: {id: 'a/b/c'}}
or{params: {id: ['a', 'b', 'c']}
. The user could easily map between the two as needed viasplit('/')
andjoin('/')
so this is really a question of "what's the best default?" FYI SvelteKit uses a string while Next.js uses an array.The text was updated successfully, but these errors were encountered: