FabienC
FabienC

Reputation: 63

Cannot read clientAddress during prerendering

I'm facing an issue with svelte prerender function : "...Cannot read clientAddress during prerendering"

I'm using SvelteKit v1.0.0-next.330 for my frontend, and I use strapi v4 for the back. My frontend is deployed on netlify and my back on heroku.

During the build process I have the following issue.

.svelte-kit/output/server/chunks/hooks-ac5d4bf3.js                               1.94 KiB
Error: Cannot read clientAddress during prerendering
    at Object.getClientAddress (file:///Users/.../node_modules/@sveltejs/kit/dist/chunks/index2.js:1294:8)
    at Object.get clientAddress [as clientAddress] (file:///Users/.../.svelte-kit/output/server/index.js:2110:22)
    at __spreadValues (file:///.../.svelte-kit/output/server/chunks/hooks-ac5d4bf3.js:11:33)
    at Object.handle (file:///.../.svelte-kit/output/server/chunks/hooks-ac5d4bf3.js:43:29)
    at respond (file:///.../.svelte-kit/output/server/index.js:2146:42)
> 500 /dashboard

In the load function of my /dashboard, I'm calling a fetch function with a relative path a .json.js endpoint. I think the issue is due to my fetch function.

try {
            let res = await fetch('/dashboard/chart.json');
...
}

If in my svelte.config I set prerender to false, the build is ok.

const config = {
    kit: {
        adapter: adapter(),
        vite: {
            plugins: [isoImport()]
        },
        prerender: {
            concurrency: 1,
            crawl: true,
            default: false,
            enabled: false
        }
    }
};

I tried changing the path to the file, to absolute path, but it's not working either.

I don't understand what's wrong, if you have any idea.

Thanks for your help

Fabien

UPDATE 1

Here is the load function within [email protected] file

<script context="module">
    
    export const load = async ({ fetch }) => {
        try {
            let res = await fetch('/dashboard/chart.json');

            if (res.ok) {
                // console.log(await res.json());
                const {
                    generateDatas,
                    apexTableSummary,
                    evolutions,
                    apexQsTable,
                    apexDonut,
                    apexColBar,
                    apexColBar2,
                    apexColBar3,
                    tableDatas
                } = await res.json();
                // console.log(generateDatas);
                return {
                    props: {
                        datas: { ...generateDatas },
                        prtRate: { ...apexTableSummary },
                        sumData: { ...evolutions },
                        qs: { ...apexQsTable },
                        donut: { ...apexDonut },
                        colBar: { ...apexColBar },
                        colBar2: { ...apexColBar2 },
                        colBar3: { ...apexColBar3 },
                        tableDatas: { ...tableDatas }
                    }
                };
            } else {
                return {
                    props: {
                        datas: {},
                        tables: {}
                    }
                };
            }
        } catch (error) {
            return {
                props: {
                    datas: {},
                    tables: {}
                }
            };
        }
    };
</script>

Here the endpoint

// récupère les données des charts

import { generateDatas, generateTablesDatas } from '$lib/dummy/chartDatas';
import {
    summaryLineDatas,
    summaryTableDatas,
    summaryDonutDatas,
    summaryColDatas,
    QSbyKeyword
} from '$lib/dummy/chartApex';

export const get = async () => {
    return {
        status: 200,
        body: {
            // lineChart,
            generateDatas: generateDatas(),

            evolutions: summaryLineDatas(20),
            apexTableSummary: summaryTableDatas(
                1,
                3,
                [
                    'Campagne',
                    'Impressions',
                    'Impressions perdues (classement)',
                    'Impressions perdues (budget)'
                ],
                null,
                ['#ff5d5d60', '#6c6ff560']
            ),
            apexQsTable: summaryTableDatas(
                9,
                3,
                ['', 'Coûts', 'Impressions', 'Clics'],
                null,
                ['#ff5d5d60', '#6c6ff560'],
                ['QS1', 'QS2', 'QS3', 'QS4', 'QS5', 'QS6', 'QS7', 'QS8', 'QS9', 'QS10']
            ),
            apexDonut: summaryDonutDatas(9, [
                'QS1',
                'QS2',
                'QS3',
                'QS4',
                'QS5',
                'QS6',
                'QS7',
                'QS8',
                'QS9',
                'QS10'
            ]),
            apexColBar: summaryColDatas(
                ['Inférieur', 'dans la moyenne', 'Supérieure à la moyenne'],
                ['CTR', 'Pertinence annonce', 'Convivialité']
            ),
            apexColBar2: summaryColDatas(
                ['Inférieur', 'dans la moyenne', 'Supérieure à la moyenne'],
                ['CTR', 'Pertinence annonce', 'Convivialité']
            ),
            apexColBar3: summaryColDatas(
                ['Inférieur', 'dans la moyenne', 'Supérieure à la moyenne'],
                ['CTR', 'Pertinence annonce', 'Convivialité']
            ),
            tableDatas: QSbyKeyword({
                nbrRow: 10,
                labels: [
                    '',
                    'Mot clé',
                    "Campagne",
                    "Groupe d'annonce",
                    'Url de destination',
                    'CPC moyen',
                    'Clics',
                    'Impressions',
                    'CTR',
                    'Coûts',
                    'Conversions',
                    'CPA (coût/conversions)',
                    'Note QS',
                    'CTR attendu',
                    "Pertinence de l'annonce",
                    'Convivialité de la page de destination'
                ]
            })
        }
    };
};

Upadte 2

I've search few days and finally, I found something. What I did, is to set my https cookies logic within my register/login svelte file. When I've change it to do it within the hooks.js handle function, it solved about everything. Not sure if it is the right answer, but now I can build my project without any issue.

Thanks

Upvotes: 1

Views: 729

Answers (1)

Lex
Lex

Reputation: 800

For me solution was like this:

// hooks.server.ts
import { building } from '$app/environment'

export const handle: Handle = async (p) => {
    if(building){
        // apply different logic here
    } else {
        const clientIp = p.event.getClientAddress()
    }
}

more details: https://svelte.dev/docs/kit/$app-environment#building

Upvotes: 0

Related Questions