I want to create dynamic pages in nextjs to match the following route users/[user]/[dashboard]. My file structure
pages/
users/
-[user].js // will match for /users/123
- index.js // will match for /users
dashboard/
- [dashboard].js // will match for /users/1234/ABCD
I'm only receiving the [user] in the query param and not the [dashboard] inside the [dashboard].js . Can someone explain how to arrange file structure to match users/[user]/[dashboard]
To match the following dynamic routes users/[user]/[dashboard] you can structure your pages folder as follows:
pages/
users/
index.js // Matches `/users` route
[user]/
index.js // Matches `/users/user123` routes
[dashboard]/
index.js // Matches `/users/user123/dashboardABC` routes
Related
Right now, my routing looks like this:
https://app.com/users opens pages/users/index.js
https://app.com/users/:userid opens pages/users/[id].js
I want to create route, for example:
https://app.com/users/:id/friends -> show all friends for the user
or even
https://app.com/users/:id/friends/:friendId -> show a specific friend
I have tried
pages
users
index.js
[id].js
friends
index.js
[friendId].js
but i can only reach users/friends and not `users/:id/friends``
How do i set my pages directory so i can use this sort of routing?
Also, I want to be able to access id and friendId in the context of getServerSideProps...
If you don't get the answer description well, pls follow the diagram I made.
If you want this https://app.com/users/:id/friends, then you should create something like this:
pages/users/index.js/[id]/index.js/friends.js
So to make this clear, you have a folder name pages (where all pages folder and files are), then you have a user folder (this takes an index.js which means user path). Now in the user folder, you have to create a folder named [id], in this folder you should create a file name index.js, this index.js stand for the :id. The last thing is to create the friend.js in the [id] folder.
Something like this.
pages ----------------- Main folder
users ------------- A folder inside `pages` folder
index.js ------- A file inside `users` folder == `https://app.com/users`
[id] ----------- A folder inside `users` folder
index.js ---- A file inside `[id]` folder ==`https://app.com/users/:id`
friends.js -- A file inside `[id]` folder == `https://app.com/users/:id/friends`
If you want something like this https://app.com/users/:id/friends/:friendId
Then you will have to do something like this:
pages ------------------------- Main folder
users --------------------- A folder inside `pages` folder
index.js --------------- A file inside `users` folder == `https://app.com/users`
[id] ------------------- A folder inside `users` folder
index.js ------------ A file inside `[id]` folder ==`https://app.com/users/:id`
[friends] -------- A folder inside `[id]` folder
index.js ------ A file inside `[friends]` folder
friendId.js --- A file inside `[friends]` folder
You can use Dynamic Routing syntax in your folders instead of a file in order to nest them (create a folder [id] instead of a file [id].js). For your specific example it would look like this:
pages
users
index.js
[id]
friends
[friendId].js
I'd like to have the following URL structure:
URL
Role
/
markdown contents of /index.md
/about
markdown contents of /about.md
/cookies
markdown contents of /cookies.md
/privacy-policy
markdown contents of /privacy-policy.md
/category1
category1 index page
/category1/post1
markdown contents of /category1/post1.md
/category1/post2
markdown contents of /category1/post2.md
/category2
category2 index page
/category2/post1
markdown contents of /category2/post1.md
/category2/post2
markdown contents of /category2/post2.md
I'd like to avoid having to create separate .js files for my content in the root directory (so no /about.js, /cookies.js, etc), but if I try something like this...
pages/
index.js
[root_article_id].js
[category]/
index.js
[category_article_id].js
... then Next.js complains because it cannot decide when I request the URL /about whether if it should use [category]/index.js or [root_article_id].js, even though I feel the latter should be called first, and if it doesn't want to deal with the request (i.e. if there's no about.md in the root of my markdown directory), then it should fall back to [category]/index.js, which still could pass the request through to the 404 handler if [category].js spits it out.
What's the correct way of structuring Next.js files for this? Do I really need to have separate .js files for my markdown files in the root content directory?
What's the correct way of structuring Next.js files for this? Do I really need to have separate .js files for my markdown files in the root content directory?
This is the easiest way since you have to somehow tell nextjs what pages you want to be articles. However, if want to avoid doing it, you can do it with rewrites.
If you know all articles (or categories), this is what you need in your next.config.js:
module.exports = {
rewrites() {
return [
{
source: "/about",
destination: "/article/about",
},
{
source: "/cookies",
destination: "/article/cookies",
},
{
source: "/privacy-policy",
destination: "/article/privacy-policy",
},
];
},
};
And then make article/[root_article_id] page. Note that rewrite does not mean redirect. The page will be available in /about but nextjs will handle it like the request was to /article/about. This means that these pages will also be available from article/about, but this can probably be prevented if for some reason necessary.
Whether you should do rewrites for articles or categories depends on which one is dynamic. If neither one is really dynamic in a sense that you know all the possible values, you should pick the one with less possible values.
If both of categories and articles are dynamic, you need to do the rewrites with middleware (beta). In your middleware you get the req and you somehow need to decide if the requested url is an article or a category page. How this is done obviously depends on where and how you store your data.
I am pretty new to python Django; I am trying to figure out what exactly I am missing from the last few hours.
here is my code structure
url.py
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('signup', views.signupuser, name="signupuser"),
path ('', views.home, name='home'),
path ('socialcard', views.create_social_card, name='create_social_card'),
path ('dashboard/', include('dashboard.urls')),
]
Then I created another URL set in the dashboard app; here is the code.
From django.shortcuts import render
# Create your views here.
def dashboard(request):
home="dashboard"
return render(request, 'dashboard.html', {'home':home})
I am getting the following error,
TemplateDoesNotExist at /dashboard/
dashboard.html
I don't know what I am missing, I have added the templates folder in the app and have also added the subfolder dashboard. like this dashboard/templates/dashboard, and then there reside dashboard.html
When I add the template path as base.html, it loads up an empty page, doesn't display any error. So I don't know what exactly I am missing.
Well as all beginners do silly mistakes...I forgot to define my app in the setting.
I would advise all beginners that add the app in the setting as soon as you start an app.
Is it possible to structure a route that contains dynamic parts in predefined format, such as /[name]-id[id], for example to have routes /bob-id303 or /mary-id205?
What I tried is create a file [name]-id[id].js. Inside getInitialProps I console.log the ctx and it contains
pathname: '/[name]-id[id]',
query: { 'name]-id[id': 'bob-id303' },
asPath: '/bob-id303',
On the other hand, calling the file [[name]]-id[id]].js gives
Failed to reload dynamic routes: Error: Optional route parameters are not yet supported ("[[name]-id[id]]").
I'd like to get the name and id directly, then pass them through initial props to the page. I'm aware I can parse asPath, but is there another way to do this?
You could use /[slug] and then do slug.split("-id"). However you may be better off doing the id alone followed by a fetch for metadata because the name could change and then that url would potentially 404.
I've fully implemented next-i18next for my NextJS website. Everything is working as it should be:
Automatically detects language using i18next middleware
Changes language with language select button
Translations with only loading in relevant namespaces etc etc
However, I would like to localise the route names so that they reflect the set language.
I understand how this can be done using next-routes and this exchange was particularly useful:
How do I localize routes with next.js and next-i18next?
In that example, routes are set up like:
routes.add('en-home', '/', 'index')
routes.add('de-home', '/de', 'index')
routes.add('en-test', '/test', 'test')
routes.add('de-test', '/de/prufung', 'test')
I tried to implement Route and Link from next-routes using the following pattern as an example:
Get current language from i18n.language
Set link url according to language set
<Link route={`${lang}-home`}></Link>
And again, using a similar pattern for next-routes Router such as:
Router.pushRoute(`${lang}-home`)
However, this is not working.
I noticed in the referenced thread that #samuelg0rd0n commented that he created a custom Link component.
Please can anybody guide me how to change all the routes according to which language the website is set to?
Thanks!
I strongly recommend you trying an official Next.js example:
Next.js -- Named routes example (next-routes)
https://github.com/zeit/next.js/tree/canary/examples/with-next-routes
But I'm seen that it needs an additional server and also will fail if we custom our app structure as my own project example:
| src/app
| -- pages
| -- post.js
| -- category.js
| -- server.js (for routes)
| src/functions
| -- index.js (lambda function for server-side)
And if I run next src/app it will fail with the following error:
Error: > Couldn't find a `pages` directory. Please create one under the project root
at findPagesDir (/home/paneladm/projects/paneladm-dev/travel-website/node_modules/next/dist/lib/find-pages-dir.js:3:170)
at new DevServer (/home/paneladm/projects/paneladm-dev/travel-website/node_modules/next/dist/server/next-dev-server.js:1:3491)
at createServer (/home/paneladm/projects/paneladm-dev/travel-website/node_modules/next/dist/server/next.js:2:105)
at Object.<anonymous> (/home/paneladm/projects/paneladm-dev/travel-website/src/app/server.js:14:13)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Function.Module.runMain (module.js:694:10)
Next.js team is working in a simple solution now
This adds an example showing how to remove the need for a custom server for an existing application using next-routes by leveraging the new custom routes support built-in to Next.js
You should update next to 9.1.+ and implement your own routes as following:
const nextRoutes = require('next-routes');
const routes = (module.exports = nextRoutes());
routes.add('category', '/category/:slug');
routes.add('post', '/post/:lang/:slug');
In your next.config.js file, enable experimental property and implement rewrites method as below:
const { routes } = require('./routes');
...
experimental: {
rewrites() {
const rewrites = [];
for (const route of routes) {
if (route.pattern !== route.page) {
rewrites.push({
source: route.pattern,
destination: route.page,
});
}
}
return rewrites;
}
},
Now your structure should be:
| src/app
| -- pages
| -- post.js
| -- category.js
But if you want to custom your pages, try change the routes like this:
...
routes.add('category/[slug]', '/category/:slug');
routes.add('post/[slug]', '/post/:lang/:slug');
It will point to pages --> category --> [slug].js file instead.
See more details in the new PR implementation files.
References
Next.js PR 9519 - Add next-routes/custom-routes example