admin管理员组文章数量:1406144
I have a next.js app that uses server side rendering. When running the application both locally and in production (on vercel edge), the initial page response is returning what looks like a javascript bundle, and not the fully rendered HTML page. This means that all my SEO is made redundant, as the first response does not contain any of the <meta/>
tags that I have defined. The page renders correctly in the browser, but I assume web scrapers only look at the initial response from the server.
Within the network tab, the first response with the "document" initiator contains the following:
<!DOCTYPE html>
<html>
<head>
<style data-next-hide-fouc="true">
body {
display: none
}
</style><noscript data-next-hide-fouc="true">
<style>
body {
display: block
}
</style>
</noscript>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="next-head-count" content="2" /><noscript data-n-css=""></noscript>
<script defer="" nomodule="" src="/_next/static/chunks/polyfills.js?ts=1665897162450"></script>
<script src="/_next/static/chunks/webpack.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/chunks/main.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/chunks/pages/_app.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/chunks/pages/index.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/development/_buildManifest.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/development/_ssgManifest.js?ts=1665897162450" defer=""></script><noscript
id="__next_css__DO_NOT_USE__"></noscript>
</head>
<body>
<div id="__next"></div>
<script src="/_next/static/chunks/react-refresh.js?ts=1665897162450"></script>
<script id="__NEXT_DATA__"
type="application/json">{"props":{"pageProps":{"properties":[{"propertyId":"OsDbKrOmE4wRRUMzalxG","propertyAvg":2.888888888888889,"landlordAvg":2.777777777777778,"imageUrl":".appspot/o/property-images%2FOsDbKrOmE4wRRUMzalxG-ZkKIwuKwYua7ml8nEWOXYIV5tiK2-6214c8e0-4aec-11ed-b51b-75adb81e8353.png?alt=media\u0026token=2437767c-0877-470a-be6a-33f34c906a09","address":"312 Brooklands Road, Timperley, Manchester, UK"},{"propertyId":"NPwjd3YMPA8ddyzqBfmO","propertyAvg":3.888888888888889,"landlordAvg":4.111111111111112,"imageUrl":".appspot/o/property-images%2FNPwjd3YMPA8ddyzqBfmO-ZkKIwuKwYua7ml8nEWOXYIV5tiK2-b8072400-4c4a-11ed-9e75-f5ca509826c3.png?alt=media\u0026token=28ef7da1-711a-485a-8282-ffa1940f767d","address":"1 Wharncliffe Road, Broomhall, Sheffield, UK"},{"propertyId":"rxabfAynk5CfTIPwdRN3","propertyAvg":3.5,"landlordAvg":3,"imageUrl":".appspot/o/property-images%2FrxabfAynk5CfTIPwdRN3-ZkKIwuKwYua7ml8nEWOXYIV5tiK2-7a025420-4c24-11ed-bbda-e9dedbc50f17.jpg?alt=media\u0026token=1da2a00b-76d0-4371-a4e0-b0c77e995db2","address":"324 Grays Inn Road, London, UK"}]},"__N_SSP":true},"page":"/","query":{},"buildId":"development","isFallback":false,"gssp":true,"scriptLoader":[{"src":"\u0026libraries=places","strategy":"afterInteractive"}]}</script>
</body>
</html>
I was under the impression that next js would render full HTML pages on the server before sending them to the browser. I am not sure if there is a way to configure a "production" build option within the next.config.js
file to make this happen, or whether this is a bug within next itself?
The following is my _app.js file:
import React from 'react';
import Head from 'next/head';
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import theme from '../config/theme';
import { AppBar, Toolbar, Typography, Container, Box } from '@mui/material';
import { MapsHomeWork } from '@mui/icons-material';
import { Auth, RouteProtect, Link } from '../ponents';
import { AuthContextProvider } from '../context/authContext';
export const App = ({ Component, pageProps }) => {
return (
<AuthContextProvider>
<Head>
<meta property="og:locale" content="en_GB" />
<meta property="og:site_name" content="Student Property Reviews" />
<meta name="viewport" content="initial-scale=1, width=device-width" />
<meta name="robots" content="index, follow" />
<link rel="icon" href="/favicon.ico" />
</Head>
<ThemeProvider theme={theme}>
<CssBaseline />
<Box>
<AppBar position='static'>
<Container maxWidth="xl">
<Toolbar disableGutters>
<Link href='/'>
<MapsHomeWork sx={{ display: { xs: 'flex', md: 'flex' }, mr: 1 }} />
<Typography
variant="h6"
sx={{
mr: 2,
display: { xs: 'none', sm: 'flex', md: 'flex' },
fontFamily: 'monospace',
fontWeight: 700,
letterSpacing: '.3rem',
color: 'inherit',
textDecoration: 'none',
}}
>
STUDENT PROPERTY REVIEW
</Typography>
</Link>
<Auth/>
</Toolbar>
</Container>
</AppBar>
<Container sx={{ marginBottom: '25px' }}>
<RouteProtect>
<Component {...pageProps} />
</RouteProtect>
</Container>
</Box>
</ThemeProvider>
</AuthContextProvider>
);
};
export default App;
Any help regarding this would be much appreciated!
I have a next.js app that uses server side rendering. When running the application both locally and in production (on vercel edge), the initial page response is returning what looks like a javascript bundle, and not the fully rendered HTML page. This means that all my SEO is made redundant, as the first response does not contain any of the <meta/>
tags that I have defined. The page renders correctly in the browser, but I assume web scrapers only look at the initial response from the server.
Within the network tab, the first response with the "document" initiator contains the following:
<!DOCTYPE html>
<html>
<head>
<style data-next-hide-fouc="true">
body {
display: none
}
</style><noscript data-next-hide-fouc="true">
<style>
body {
display: block
}
</style>
</noscript>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="next-head-count" content="2" /><noscript data-n-css=""></noscript>
<script defer="" nomodule="" src="/_next/static/chunks/polyfills.js?ts=1665897162450"></script>
<script src="/_next/static/chunks/webpack.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/chunks/main.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/chunks/pages/_app.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/chunks/pages/index.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/development/_buildManifest.js?ts=1665897162450" defer=""></script>
<script src="/_next/static/development/_ssgManifest.js?ts=1665897162450" defer=""></script><noscript
id="__next_css__DO_NOT_USE__"></noscript>
</head>
<body>
<div id="__next"></div>
<script src="/_next/static/chunks/react-refresh.js?ts=1665897162450"></script>
<script id="__NEXT_DATA__"
type="application/json">{"props":{"pageProps":{"properties":[{"propertyId":"OsDbKrOmE4wRRUMzalxG","propertyAvg":2.888888888888889,"landlordAvg":2.777777777777778,"imageUrl":"https://firebasestorage.googleapis./v0/b/student-property-1577144888882.appspot./o/property-images%2FOsDbKrOmE4wRRUMzalxG-ZkKIwuKwYua7ml8nEWOXYIV5tiK2-6214c8e0-4aec-11ed-b51b-75adb81e8353.png?alt=media\u0026token=2437767c-0877-470a-be6a-33f34c906a09","address":"312 Brooklands Road, Timperley, Manchester, UK"},{"propertyId":"NPwjd3YMPA8ddyzqBfmO","propertyAvg":3.888888888888889,"landlordAvg":4.111111111111112,"imageUrl":"https://firebasestorage.googleapis./v0/b/student-property-1577144888882.appspot./o/property-images%2FNPwjd3YMPA8ddyzqBfmO-ZkKIwuKwYua7ml8nEWOXYIV5tiK2-b8072400-4c4a-11ed-9e75-f5ca509826c3.png?alt=media\u0026token=28ef7da1-711a-485a-8282-ffa1940f767d","address":"1 Wharncliffe Road, Broomhall, Sheffield, UK"},{"propertyId":"rxabfAynk5CfTIPwdRN3","propertyAvg":3.5,"landlordAvg":3,"imageUrl":"https://firebasestorage.googleapis./v0/b/student-property-1577144888882.appspot./o/property-images%2FrxabfAynk5CfTIPwdRN3-ZkKIwuKwYua7ml8nEWOXYIV5tiK2-7a025420-4c24-11ed-bbda-e9dedbc50f17.jpg?alt=media\u0026token=1da2a00b-76d0-4371-a4e0-b0c77e995db2","address":"324 Grays Inn Road, London, UK"}]},"__N_SSP":true},"page":"/","query":{},"buildId":"development","isFallback":false,"gssp":true,"scriptLoader":[{"src":"https://maps.googleapis./maps/api/js?key=AIzaSyAyIxfU1kI6ODZLE80-_XXyK7tdmY3Gk50\u0026libraries=places","strategy":"afterInteractive"}]}</script>
</body>
</html>
I was under the impression that next js would render full HTML pages on the server before sending them to the browser. I am not sure if there is a way to configure a "production" build option within the next.config.js
file to make this happen, or whether this is a bug within next itself?
The following is my _app.js file:
import React from 'react';
import Head from 'next/head';
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import theme from '../config/theme';
import { AppBar, Toolbar, Typography, Container, Box } from '@mui/material';
import { MapsHomeWork } from '@mui/icons-material';
import { Auth, RouteProtect, Link } from '../ponents';
import { AuthContextProvider } from '../context/authContext';
export const App = ({ Component, pageProps }) => {
return (
<AuthContextProvider>
<Head>
<meta property="og:locale" content="en_GB" />
<meta property="og:site_name" content="Student Property Reviews" />
<meta name="viewport" content="initial-scale=1, width=device-width" />
<meta name="robots" content="index, follow" />
<link rel="icon" href="/favicon.ico" />
</Head>
<ThemeProvider theme={theme}>
<CssBaseline />
<Box>
<AppBar position='static'>
<Container maxWidth="xl">
<Toolbar disableGutters>
<Link href='/'>
<MapsHomeWork sx={{ display: { xs: 'flex', md: 'flex' }, mr: 1 }} />
<Typography
variant="h6"
sx={{
mr: 2,
display: { xs: 'none', sm: 'flex', md: 'flex' },
fontFamily: 'monospace',
fontWeight: 700,
letterSpacing: '.3rem',
color: 'inherit',
textDecoration: 'none',
}}
>
STUDENT PROPERTY REVIEW
</Typography>
</Link>
<Auth/>
</Toolbar>
</Container>
</AppBar>
<Container sx={{ marginBottom: '25px' }}>
<RouteProtect>
<Component {...pageProps} />
</RouteProtect>
</Container>
</Box>
</ThemeProvider>
</AuthContextProvider>
);
};
export default App;
Any help regarding this would be much appreciated!
Share Improve this question edited Oct 17, 2022 at 0:36 J. Whitehead asked Oct 16, 2022 at 5:36 J. WhiteheadJ. Whitehead 5314 silver badges28 bronze badges 4-
What does your
_app
looks like? You're most likely forcing client-side rendering somehow. – juliomalves Commented Oct 16, 2022 at 11:32 - What would cause client-side rendering in _app? All that ponent does is return markup (using MUI ponents) – J. Whitehead Commented Oct 17, 2022 at 0:31
-
That's what I'm trying to understand. You must have some code that's causing it. Sharing the code for
_app
and the page you're rendering would help clarify it. – juliomalves Commented Oct 17, 2022 at 0:34 - I will add it to the original post – J. Whitehead Commented Oct 17, 2022 at 0:36
2 Answers
Reset to default 4I figured this issue out. I had tried everything I thought I could, but when menting out the <AuthContextProvider/>
it seemed to work pletely fine!
Within the auth context file, I was performing conditional rendering, depending on a loading
state, which was causing SSR not to take place:
Previously:
const AuthContext = createContext({});
export const useAuth = () => useContext(AuthContext);
export const AuthContextProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const provider = new GoogleAuthProvider();
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
setUser(user ? user : null);
setLoading(false);
});
return () => unsubscribe();
}, []);
const login = () => {
return signInWithRedirect(auth, provider);
};
const logout = async () => {
setUser(null);
await signOut(auth);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{!loading && children}
</AuthContext.Provider>
);
};
Now:
const AuthContext = createContext({});
export const useAuth = () => useContext(AuthContext);
export const AuthContextProvider = ({ children }) => {
const [user, setUser] = useState(null);
const provider = new GoogleAuthProvider();
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
setUser(user ? user : null);
});
return () => unsubscribe();
}, []);
const login = () => {
return signInWithRedirect(auth, provider);
};
const logout = async () => {
setUser(null);
await signOut(auth);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
Well, there are many reasons why there is no rendering HTML the most mon problem is there is something that is blocking the rendering, I give an example using Redux-Persist blocks totally the rendering so when you right-click on the page and click on page source
you will see not HTML rendering, so you need to check what packages are blocking the rendering because not all NPM packages are very friendly
with NextJS and make these behaviors.
本文标签:
版权声明:本文标题:javascript - Next js app with SSR is not pre-rendering HTML, so web-scrapers cannot access the content - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744975266a2635476.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论