feat: Setup GraphQL with dynamic node routing logic

This commit is contained in:
2026-03-18 23:21:05 -04:00
parent 1838d59382
commit 3b72a16f86
9 changed files with 1291 additions and 73 deletions

View File

@@ -1,3 +1,3 @@
{ {
"recommendations": ["oxc.oxc-vscode"] "recommendations": ["graphql.vscode-graphql", "oxc.oxc-vscode"],
} }

View File

@@ -0,0 +1,3 @@
fragment NodePage on Page {
title @nonNull
}

View File

@@ -0,0 +1,8 @@
<script setup lang="ts">
import type { NodePageFragment } from "#graphql/types";
defineProps<{ node: NodePageFragment }>();
</script>
<template>
<div id="node-page">{{ node.title }}</div>
</template>

View File

@@ -0,0 +1,8 @@
query NodeByUri($uri: String!) {
nodeByUri(uri: $uri) @nonNull {
__typename
... on Page {
...NodePage
}
}
}

View File

@@ -1,5 +1,39 @@
<script setup lang="ts">
// Fetch node by URI and handle query errors
const { path: uri } = useRoute();
const { data: node, error } = await useAsyncGraphQLQuery(
"NodeByUri",
{ uri },
{
transform: ({ nodeByUri }) => nodeByUri,
},
);
// Handle errors and missing nodes
if (!node.value) {
console.error("NodeByUri query error:", error.value);
throw createError({
statusCode: 404,
message: `La page demandée est introuvable: ${uri}`,
fatal: true,
});
}
// Dynamically resolve component based on node type
const componentName = `Node${node.value.__typename}`;
if (!useNuxtApp().vueApp.component(componentName)) {
throw createError({
statusCode: 404,
message: `La page demandée ne peut pas être affichée correctement: ${componentName}`,
fatal: true,
});
}
</script>
<template> <template>
<div id="page-node-from-uri"> <div id="page-node-from-uri">
<PageHeader title="TODO" /> <Component :is="componentName" :node="node" />
</div> </div>
</template> </template>

View File

@@ -0,0 +1,17 @@
{
"schema": "./.nuxt/graphql/schema.graphql",
"documents": [
"./app/**/*.{gql,ts,vue}",
"./server/**/*.{gql,ts}",
"./shared/**/*.{gql,ts}"
],
"extensions": {
"codegen": {
"config": {
"scalars": {
"ZodValue": "unknown"
}
}
}
}
}

View File

@@ -1,13 +1,36 @@
// WordPress backend URL (required)
const wpUrl = process.env.NUXT_WP_URL;
if (!wpUrl) {
throw new Error("NUXT_WP_URL environment variable is not set");
}
console.log(`${wpUrl}/graphql`);
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({ export default defineNuxtConfig({
modules: ["@nuxt/ui", "nuxt-svgo"], modules: ["@lewebsimple/nuxt-graphql", "@nuxt/ui", "nuxt-svgo"],
compatibilityDate: "2026-03-18", compatibilityDate: "2026-03-18",
devtools: { enabled: true }, devtools: { enabled: true },
vite: {
optimizeDeps: {
include: ["@vue/devtools-core", "@vue/devtools-kit", "zod"],
},
},
graphql: {
server: {
schema: [{ type: "remote", endpoint: `${wpUrl}/graphql` }],
},
},
ui: { colorMode: false }, ui: { colorMode: false },
css: ["~/assets/css/_main.css"], css: ["~/assets/css/_main.css"],
components: { dirs: [{ path: "~/components", pathPrefix: false }] }, components: {
dirs: [
{ path: "~/components/nodes", global: true },
{ path: "~/components", pathPrefix: false },
],
},
svgo: { svgo: {
autoImportPath: "~/assets/svg/", autoImportPath: "~/assets/svg/",

View File

@@ -16,6 +16,7 @@
"release": "oxlint . && oxfmt --check . && nuxt typecheck && changelogen --noAuthors --release --push" "release": "oxlint . && oxfmt --check . && nuxt typecheck && changelogen --noAuthors --release --push"
}, },
"dependencies": { "dependencies": {
"@lewebsimple/nuxt-graphql": "^0.7.5",
"@nuxt/ui": "^4.5.1", "@nuxt/ui": "^4.5.1",
"nuxt": "^4.4.2", "nuxt": "^4.4.2",
"nuxt-svgo": "^4.2.6", "nuxt-svgo": "^4.2.6",
@@ -24,6 +25,7 @@
"vue-router": "^5.0.3" "vue-router": "^5.0.3"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^25.5.0",
"changelogen": "^0.6.2", "changelogen": "^0.6.2",
"oxfmt": "^0.41.0", "oxfmt": "^0.41.0",
"oxlint": "^1.56.0", "oxlint": "^1.56.0",

File diff suppressed because it is too large Load Diff