Как можно обновить head в next.js?
Всем привет, может подскажите решение получше или попроще.
На сайте реализовано отображение страниц в модельном окне, при этом меняется URL и принудительно меняю пока что только title в head
Дело в том что в head есть еще куча всего что лучше бы поменять при открытии модельного окна, есть ли варианты как можно все это упростить и не перебирать каждый элемент.
На странице новости я формирую head отдельным компонентом
post.tsx
const Post = ({ ...props }) => { return ( <> <HeadComponent title={title} description={description} keywords={keywords} image={post.image} ogTitle={ogTitle} ogDescription={ogDescription} ogCreditText={ogCreditText} post={post} /> <div> // Тут сам контент </div> </> ) } export default observer(Post) |
const Post = ({ ...props }) => { return ( <> <HeadComponent title={title} description={description} keywords={keywords} image={post.image} ogTitle={ogTitle} ogDescription={ogDescription} ogCreditText={ogCreditText} post={post} /> <div> // Тут сам контент </div> </> ) } export default observer(Post)
HeadComponent.tsx
const HeadComponent = ({ ...props }) => { <Head> <title>{props.title}</title> <meta name="description" content={props.description} /> // И т.д. </Head> } |
const HeadComponent = ({ ...props }) => { <Head> <title>{props.title}</title> <meta name="description" content={props.description} /> // И т.д. </Head> }
При открытии модельного окна у меня есть все данные для формирования HeadComponent в обработчике при клике по ссылке
const handleClick = useCallback((e) => { // Тут переменные со всеми нужными данными const head = <HeadComponent title={title} description={description} keywords={keywords} image={image} ogTitle={ogTitle} ogDescription={ogDescription} ogCreditText={ogCreditText} post={post} /> console.log(head) // {$$typeof: Symbol(react.element), type: {…}, key: null, ref: null, props: {…}, …} window.history.pushState({ ...window.history.state, id: link.getAttribute("data-id"), }, title, link.pathname ) context.openModal(true) // открывает модельное окно и там дальше в него подгружаются данные }, []) |
const handleClick = useCallback((e) => { // Тут переменные со всеми нужными данными const head = <HeadComponent title={title} description={description} keywords={keywords} image={image} ogTitle={ogTitle} ogDescription={ogDescription} ogCreditText={ogCreditText} post={post} /> console.log(head) // {$$typeof: Symbol(react.element), type: {…}, key: null, ref: null, props: {…}, …} window.history.pushState({ ...window.history.state, id: link.getAttribute("data-id"), }, title, link.pathname ) context.openModal(true) // открывает модельное окно и там дальше в него подгружаются данные }, [])
Я вот чего думаю, можно ли как то пушнуть новый head в документ?
Дополнительно:
Зачем только?
Так как судя по всему это pages dir , то параллельные роуты тут не работают насколько я знаю.
Так же могу посоветовать использовать пакет next-seo. возможно он позволяет это делать
ну и никто не мешает напрямую менять tilte/description и тд
document.title = 'title'
Я бы использовал существующий компонент Head, вместе с контекстом и состоянием, а так же кастомный HeadProvider:
// _app.js import {HeadProvider} from './HeadProvider'; function App({Component, pageProps}) { return ( <HeadProvider> <Component {...pageProps} /> </HeadProvider> ); } |
// _app.js import {HeadProvider} from './HeadProvider'; function App({Component, pageProps}) { return ( <HeadProvider> <Component {...pageProps} /> </HeadProvider> ); }
// HeadProvider.js import React, {createContext, useContext, useState} from 'react'; const HeadContext = createContext(); export const useHead = () => useContext(HeadContext); export function HeadProvider({children}) { const [headData, setHeadData] = useState({ title: 'Init title', description: 'Init description', keywords: 'Init keywords' }); return ( <HeadContext.Provider value={{headData, setHeadData}}> {children} </HeadContext.Provider> ); } |
// HeadProvider.js import React, {createContext, useContext, useState} from 'react'; const HeadContext = createContext(); export const useHead = () => useContext(HeadContext); export function HeadProvider({children}) { const [headData, setHeadData] = useState({ title: 'Init title', description: 'Init description', keywords: 'Init keywords' }); return ( <HeadContext.Provider value={{headData, setHeadData}}> {children} </HeadContext.Provider> ); }
// MyBestHead.js import Head from 'next/head'; import {useHead} from './HeadProvider'; export function MyBestHead() { const {headData} = useHead(); return ( <Head> <title>{headData.title}</title> <meta name="description" content={headData.description}/> {/* more head items */} </Head> ); } |
// MyBestHead.js import Head from 'next/head'; import {useHead} from './HeadProvider'; export function MyBestHead() { const {headData} = useHead(); return ( <Head> <title>{headData.title}</title> <meta name="description" content={headData.description}/> {/* more head items */} </Head> ); }
// MyComponent.js import React, {useCallback} from 'react'; import {useHead} from './HeadProvider'; export function MyComponent() { const {setHeadData} = useHead(); const handleClick = useCallback(() => { setHeadData({ title: 'New title', description: 'New description', keywords: 'New keywords' }); }, [setHeadData]); return ( <button onClick={handleClick}>Update Head Data</button> ); } |
// MyComponent.js import React, {useCallback} from 'react'; import {useHead} from './HeadProvider'; export function MyComponent() { const {setHeadData} = useHead(); const handleClick = useCallback(() => { setHeadData({ title: 'New title', description: 'New description', keywords: 'New keywords' }); }, [setHeadData]); return ( <button onClick={handleClick}>Update Head Data</button> ); }
- Интересная реализация, т.е. по факту нужно будет просто пушить новое состояние. Сейчас попробую =) Спасибо!
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для обновления `` в Next.js можно воспользоваться компонентом `NextHead` из пакета `next/head`. Этот компонент позволяет динамически изменять содержимое `` на страницах вашего приложения.
Вот пример использования компонента `NextHead` для обновления `` в Next.js:
```html
import Head from 'next/head'; function MyPage() { return ( <div> <title>Моя Страница</title> <h1>Добро пожаловать на мою страницу!</h1> </div> ); } export default MyPage;
```
В этом примере мы импортируем компонент `Head` из пакета `next/head` и используем его внутри компонента `MyPage`. Мы добавляем теги `
Таким образом, вы можете динамически обновлять содержимое `` на страницах вашего приложения Next.js, используя компонент `NextHead`. Надеюсь, это поможет вам решить проблему обновления `` в вашем приложении!