Вы можете столкнуться с ситуацией, когда вам нужно получить ссылку на документ в приложении 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();
    }
}