Comments (8)
Another example of the context
object is this one translatePathFromContext()
which basically expects an object with the slug attribute: https://github.com/chapter-three/next-drupal/blob/main/packages/next-drupal/src/client.ts#L962
Trying to convert to App Router, where we don't have anymore the context object, the only way I found to convert this one https://github.com/chapter-three/next-drupal-basic-starter/blob/main/pages/%5B...slug%5D.tsx, is:
export default async function Page({ params }: any) {
const resource = await getPage(params);
return (
<Layout>
<Head>
<title>{resource.title}</title>
<meta name="description" content="A Next.js site powered by Drupal." />
</Head>
{resource.type === "node--page" && <NodeBasicPage node={resource} />}
{resource.type === "node--article" && <NodeArticle node={resource} />}
</Layout>
);
}
async function getPage(args: any) {
const path = await drupal.translatePathFromContext({ params: args });
if (!path) {
return {
notFound: true,
};
}
const type = path.jsonapi?.resourceName;
let params = {};
if (type === "node--article") {
params = {
include: "field_image,uid",
};
}
const resource = await drupal.getResourceFromContext<DrupalNode>(path, args, {
params,
});
// At this point, we know the path exists and it points to a resource.
// If we receive an error, it means something went wrong on Drupal.
// We throw an error to tell revalidation to skip this for now.
// Revalidation can try again on next request.
if (!resource) {
throw new Error(`Failed to fetch resource: ${path.jsonapi?.individual}`);
}
return resource;
}
It mostly works, but yet, not sure if I'm (ab)using the API by manually crafting the context object.
from next-drupal.
Thank you for providing this project, it is greatly appreciated.
Currently, I am exploring the possibility of converting the starter to the app router using the latest library, specifically the one found at https://www.npmjs.com/package/next-drupal/v/0.0.0-pr.600.128d03bc.
My objective at the moment is to gain a better understanding of how to migrate an existing project.
So far everything is working fine, however, I believe I may be missing something important.
Several functions utilize the context
object, such as getResourceFromContext,
which originates from the pages router, as seen here: https://github.com/chapter-three/next-drupal/blob/main/packages/next-drupal/src/get-resource.ts#L17.
How should I proceed with the conversion process? Would it be necessary to create a custom context
object?
from next-drupal.
@JohnAlbin sorry for coming back on this. Can you help me to understand how the context
object should be treated in the app router context ?
from next-drupal.
The context
object is what I'm struggling with at the moment as well.
Let's walk through the old pages/[...slug].tsx
flow so we all (including me) understand it.
How the old pages/[...slug].tsx
works
Next.js runs getStaticPaths
getStaticPaths
receives a context object:type GetStaticPathsContext = { locales?: string[] defaultLocale?: string }
getStaticPaths
callsdrupal.getStaticPathsFromContext(RESOURCE_TYPES, context)
getStaticPaths
returnspaths
which is an array of strings representing aslug
for each page.
Next.js runs getStaticProps
per entry in the paths
array.
getStaticProps
receives a slightly different context object:Thetype GetStaticPropsContext = { params?: Params preview?: boolean previewData?: Preview draftMode?: boolean locale?: string locales?: string[] defaultLocale?: string }
context.params
is one of the items in thepaths
array returned bygetStaticPaths
getStaticProps
then callsdrupal.translatePathFromContext(context)
translatePathFromContext
usescontext.params?.slug
RED FLAGslug
is a convention, not a specific property name. If the name of this file was[...path]
, the param would bepath
notslug
. Also, looking at Next.js docs, this param is supposed to be an array of strings (each part in a path likesome/slug1/slug2
), not a single string; but ourdrupal.getStaticPathsFromContext
returns a singlestring
and not astring[]
.translatePathFromContext
returnspath: DrupalTranslatedPath
getStaticProps
gets the entity type frompath?.jsonapi?.resourceName
so that it knows which fields it should be asking for when it requests the entity and which React component to use to render the entity.getStaticProps
callsdrupal.getResourceFromContext( path, context, { params })
wherepath
is aDrupalTranslatedPath
,context
is aGetStaticPropsContext
, andparams
is the list of fields, sorting, etc.getStaticProps
returns theresource
that is returned from the previous step.
For each call to getStaticProps
, Next.js renders the NodePage
component with the resource
prop returned from that getStaticProps
call.
How a new app/[...slug]/page.tsx
should work
Next.js runs generateStaticParams
-
generateStaticParams
is given anoptions
object that contains theparams
from any parent directory dynamic routes. See https://nextjs.org/docs/app/api-reference/functions/generate-static-params#parameters In thenext-drupal
starters, there's no parent dynamic route, soparams
is empty. -
generateStaticParams
shouldn't calldrupal.getStaticPathsFromContext(RESOURCE_TYPES, context)
because there is nocontext
object. We'll need a new method to use and one doesn't exist right now. But in the interim, we can calldrupal.getStaticPathsFromContext(RESOURCE_TYPES,{})
-
generateStaticParams
returns an array ofparams
objects where one of the param property names MUST match the filename if it's a dynamic route filename. examples:- If used is in
[category].tsx
, the returned data should match{ category: string }[]
- If used is in
[...slug].tsx
, the returned data should match{ slug: string[] }[]
That means we'll need to let the developer massage the data returned by
drupal.getStaticPathsFromContext()
(or what we replace it with). - If used is in
Next.js has removed the old getStaticProps
step. So all of the old sub-steps need to be moved to the next step.
Lastly, Next.js renders a page using the NodePage
component for each entry in the params
array returned by generateStaticParams
NodePage
will need to check if draft mode is on withdraftMode().isEnabled
and, if it is, then figure out how to determine which revision Drupal wants us to show (TBD: Cookies?).NodePage
should calldrupal.translatePath(params.slug[0])
to get thepath: DrupalTranslatedPath
NodePage
gets the entity uuid frompath.entity.uuid
and the entity type frompath?.jsonapi?.resourceName
so that it knows which fields it should be asking for when it requests the entity and which React component to use to render the entity.NodePage
callsdrupal.getResource(type, uuid, { params })
with the path or uuid and the revision ID of the desired entity andparams
, which is the list of fields, sorting, etc.NodePage
then finishes rendering the returned entity.
from next-drupal.
@JohnAlbin, first of all, let me say thank you so much for your super detailed answers. Give me some time to connect all the dots, and hopefully, I can contribute back with some code too.
from next-drupal.
@JohnAlbin I've created a diagram of the Pages Router flow. I would appreciate your feedback before I continue with the other flow.
You can find it here: https://excalidraw.com/#room=f28794c0ac45452180bf,1OOdKSnoZByreHn6SkkZhA
And here as an attachment, just remove .txt part of the extension.
next-drupal-diagram-1.excalidraw.txt
from next-drupal.
I've just added to the diagram even the new app router workflow, as you've described, it is the same link and attaached.
next-drupal-diagram-2.excalidraw.txt
from next-drupal.
I've updated my comment above showing “NodePage
calls drupal.getResource(type, uuid, { params })
”. I figured that out when adding the examples/example-router-migration
to the next-drupal repo. https://github.com/chapter-three/next-drupal/tree/main/examples/example-router-migration
from next-drupal.
Related Issues (20)
- I did all the necessary configuration, but I can't see the preview mode in drupal HOT 1
- Images path not correct
- Problem with building example-marketing.
- code coverage reporting is flakey HOT 5
- Make Subrequests module optional HOT 1
- docs: incorrect api route in docs to implement search API
- NextDrupalBase cannot be used in enableDraftMode()
- getMenu function fails to fetch menu.
- Looking for advice on creating paginated front end term pages with mixed-bundle content HOT 1
- Access control: is it a problem to uncheck 'Bypass content access control' permission for my oAuth consumer?
- next-drupal 1.6 npm package works with next 14, but has 13 as a dependency, triggering high vulnerability HOT 2
- Add NextFetchRequestConfig, such as next.revalidate, to fetch requests HOT 1
- Add support for Drupal cache tags in the revalidate functionality
- OAuth token expires
- Offset not working if query has fields param
- A single Drupal instance with many front-ends (Next.Js applications)
- Proposal: Enhance Documentation and Provide Implementation Examples for next-drupal NPM Package
- Proposal: Enhance Documentation and Provide Implementation Examples for next-drupal NPM Package
- Optimize `next-drupal` to provide an option for returning only necessary data for front-end applications
- Unpublishing a published page does not revalidate
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from next-drupal.