Вы можете столкнуться с ситуацией, когда вам нужно получить ссылку на документ в приложении NextJS. Реферер можно использовать в аналитике, чтобы вы могли проанализировать, откуда пользователь посещает ваш сайт.
Получение реферера и пути запроса на сервере
В NextJS при рендеринге страницы вы можете получить доступ к контексту (ctx) в файле _app.tsx, как показано ниже.
class App extends App<AppInterface, AppProps> { static async getInitialProps(props) { let referringURL; let requestingURL; const { ctx } = props; if (ctx.isServer) { referringURL = ctx.req.headers.referer; requestingURL = ctx.req.reqPath; } // you can dispatch them to store // ctx.store.dispatch() return { referringURL, requestingURL } } render() { const { Component, pageProps } = this.props; // pageProps is nothing but your object returned from the // getInitialProps() return ( <Provider store={store}> <Component /> </Provider> ); } }
Получение реферера и пути запроса на клиенте и сервере
Маршрутизатор NextJS предоставляет события, на которые мы можем подписаться при монтировании компонента. Поэтому лучший способ добиться этого — сохранить активную страницу и состояние реферера в хранилище избыточности.
import Router from 'next/router'; const updateStoreActivePage = (activePage, bRefererToo) => (dispatch, getState) => { const state = getState(); const currentPage = state.digitalData.activePage; dispatch({ type: constants.UPDATE_DIGITAL_DATA_ACTIVEPAGE, payload: { activePage, ...(bRefererToo ? { referer: currentPage } : {}), }, }); }; export class BeforeHistoryChange { private static UpdateActivePage; private static BindStore(props) { BeforeHistoryChange.UpdateActivePage = ({ store }) => { const { dispatch } = store; return async (activePage, bReferrerToo = true) => { await dispatch(updateStoreActivePage(activePage, bReferrerToo)); return Promise.resolve(); }; }; } static Subscribe(props) { BeforeHistoryChange.BindStore(props); Router.events.on('beforeHistoryChange', BeforeHistoryChange.UpdateActivePage); } static Unsubscribe() { Router.events.off('beforeHistoryChange', BeforeHistoryChange.UpdateActivePage); } } class App extends App<AppInterface, AppProps> { static async getInitialProps(props) { let referringURL; let requestingURL; const { ctx } = props; if (ctx.isServer) { referringURL = ctx.req.headers.referer; requestingURL = ctx.req.reqPath; } // you can dispatch them to store // ctx.store.dispatch() return { referringURL, requestingURL } } render() { const { Component, pageProps } = this.props; // pageProps is nothing but your object returned from the // getInitialProps() return ( <Provider store={store}> <Component /> </Provider> ); } componentDidMount() { // Subscribe to client side events on component mount RouterEvents.Subscribe(this.props); } componentWillUnmount() { // Unsubscribe to the events just before unmount RouterEvents.Unsubscribe(); } }