I'm trying to make a web UI for the Philips Hue API. This involves sending http requests over the users' private network to communicate with their hue bridge device. Is this possible? I'm currently trying to do it on a page load using axios, but it doesn't seem to execute on the client side. This would likely be a giant security vulnerability if possible, so I'm thinking it's not. Just wondering if anyone has experience trying to do something like this.
An example of my sveltekit code:
export const load: PageLoad = (async () => {
try {
const headers = new AxiosHeaders();
headers.set('hue-application-key', BRIDGE_USERNAME);
const res = await axios.request({
url: `https://${BRIDGE_IP}/clip/v2/resource/light`,
headers: headers,
method: 'GET',
httpsAgent: new https.Agent({
checkServerIdentity: (hostname: string, cert: PeerCertificate) => {
// Make sure the peer certificate's common name is equal to
// the Hue bridgeId that this request is for.
if (cert.subject.CN === BRIDGE_SERVER_NAME) {
return undefined;
} else {
return new Error('Server identity check failed. CN does not match bridgeId.');
}
},
ca: BRIDGE_SSL_CERT,
}),
});
if (!res.data) {
throw error(500, 'No data returned from bridge');
}
return res.data
} catch (err) {
return { error: 'Failed to load lights' };
}
}) satisfies PageLoad;
I expect this to run on the client and retrieve data from the hue bridge, but it only seems to work server-side.
By default, SvelteKit pages are rendered on the server (SSR) for the initial request and in the browser (CSR) for subsequent navigation. Take a look at the documentation here.
It is very likely that you are seeing the output of the server side only because you didn't navigate back and forth to this page after the initial render (refreshing the page is also considered an initial render).
If you want the
+page.tsto only run on the client, you can set thessrvariable to false:This will force the page to render on the client only even for the initial request. At this point, you should see whether the request was successful or not in the browser itself.
Alternatively, if you still want some code to be run on the server for the initial render, you can move your request code to inside the
onMountmethod in the+page.sveltefile: