Currently I'm trying to make a page with Next.js with pages/api
feature pointing to graphql
with graphql-yoga
dependency and getting the data from mongoose
http://localhost:3000/api/graphql
.
My goal is to make a SSR page with combining getServerSideProps()
and swr
for data fetcher to get data from GraphQL URL.
I successfully did that, but the problem is when I disable JavaScript (in Chrome) and then refresh the page the data and CSS is not rendering as expected.
Before ( Javascript Enabled )
After ( Javascript Disabled )
Here is my Source Code:
pages/api/graphql.js
:
import { createServer } from '@graphql-yoga/node'
import resolvers from 'models/graphql/resolvers'
import typeDefs from 'models/graphql/typeDefs'
import dbConnect from '../../dbConnect'
dbConnect()
const server = createServer({
schema: {
typeDefs,
resolvers,
},
endpoint: '/api/graphql',
})
export default server
dbConnect.js
const mongoose = require('mongoose')
const MongoDb = process.env.MONGODB_URI
const connectDb = async () => {
try {
await mongoose.connect(MongoDb, {
useNewUrlParser: true,
useUnifiedTopology: true
})
console.log('db success connect')
} catch (err) {
console.log('error connecting to database')
console.log(err)
process.exit(1)
}
}
export default connectDb
index.js
import Home from "components/home";
import useSWR, { SWRConfig } from "swr";
import booksQuery from 'models/graphql/queries/books'
const graphqlUrl = "http://localhost:3000/api/graphql";
const fetcher = (query) =>
fetch(graphqlUrl, {
method: 'POST',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify({ query }),
})
.then((res) => res.json())
.then((json) => json.data)
export async function getServerSideProps() {
const repoInfo = await fetcher(booksQuery);
return {
props: {
fallback: {
[graphqlUrl]: repoInfo
}
}
};
}
function Repo() {
const { data, error } = useSWR(booksQuery, fetcher);
if (error) return "An error has occurred.";
if (!data) return "Loading...";
const { books} = data
return <Home data={books} />
}
export default function Index({ fallback }) {
return (
<SWRConfig value={{fallback}}>
<Repo />
</SWRConfig>
)
}
How did this happen and what is the solution to make the render the same as with JavaScript enabled?
CodePudding user response:
When javascript in the browser is disabled, the contents loading from the server only works (SSR). The contents painted from the client side (dynamic DOM CSS) won't work.
For better handling, you can show a message to the user using noscript. noscrirpt will run when javascript is disabled.
<noscript>
<img src="no_js.gif" alt="Javascript not enabled" />
</noscript>
CodePudding user response:
The key in the useSWR
call needs to match the fallback key used in getServerSideProps
.
In your case this means you should use the booksQuery
value as a key rather than graphqlUrl
, so it matches in both situations.
export async function getServerSideProps() {
const repoInfo = await fetcher(booksQuery);
return {
props: {
fallback: {
[booksQuery]: repoInfo
}
}
};
}
const { data, error } = useSWR(booksQuery, fetcher);
// ^ Same key value as `fallback`. `data` will be populated correctly during SSR.