Closed SamuelEarl closed 6 years ago
Hola! So here's the deal, between open source and my day job and life and what not, I have a lot to manage, so I use a GitHub bot to automate a few things here and there. This particular GitHub bot is going to mark this as stale because it has not had recent activity for a while. It will be closed if no further activity occurs in a few days. Do not take this personally--seriously--this is a completely automated action. If this is a mistake, just make a comment, DM me, send a carrier pidgeon, or a smoke signal.
ProBot automatically closed this due to inactivity. Holler if this is a mistake, and we'll re-open it.
How can I get this added in the examples directory?
static route in the example above doesn't work. below is working example (replace 'static' to your value if it differs):
await server.route({
method: 'GET',
path: '/static/{file*}',
handler: {
directory: {
path: process.env.RAZZLE_PUBLIC_DIR + '/static'
}
}
});
note: process.env.RAZZLE_PUBLIC_DIR is a full path in the filesystem. note2: robots.txt and favicon.ico isn't served by that route (they are not nested in /static)
Hi I was able to integrate hapi with latest razzle version, but cannot find a way on how to auto-reload the server. Could you please help?
Want to just add here for anyone who would find this in 2200 AD
Change request.url to request.url.pathname
This is the full correct HapiJS Server with Redux! Replace CONFIG stuff with your stuff
import * as Hapi from "@hapi/hapi";
import * as Inert from "@hapi/inert";
import * as Vision from "@hapi/vision";
import React from "react";
import { renderToString } from "react-dom/server";
import Helmet from "react-helmet";
import { Provider } from "react-redux";
import { StaticRouter } from "react-router-dom";
import serialize from "serialize-javascript";
import CONFIG from "../configs/gconfig";
import App from "./App";
import configureStore from "./configureStore";
// prettier-ignore
const regex = /[^\\]*\.(\w+)$/;
const assets = require(process.env.RAZZLE_ASSETS_MANIFEST);
const cssLinksFromAssets = (assets, entrypoint) => {
return assets[entrypoint]
? assets[entrypoint].css
? assets[entrypoint].css
.map((asset) => `<link rel="stylesheet" href="${asset}">`)
.join("")
: ""
: "";
};
const jsScriptTagsFromAssets = (assets, entrypoint, extra = "") => {
return assets[entrypoint]
? assets[entrypoint].js
? assets[entrypoint].js
.map((asset) => `<script src="${asset}"${extra}></script>`)
.join("")
: ""
: "";
};
const ser = async () => {
const plugins = [
{
plugin: Inert,
},
{
plugin: Vision,
},
];
const server = Hapi.server({
port: process.env.PORT ? parseInt(process.env.PORT, 10) : 3000,
host: "localhost",
});
try {
await server.register(plugins);
} catch (err) {
console.log(err);
}
// Static Files Generated by Razzle
await server.route({
method: "GET",
path: "/static/{file*}",
handler: {
directory: {
path: process.env.RAZZLE_PUBLIC_DIR + "/static",
},
},
});
// Test Route
server.route({
method: "GET",
path: "/test",
async handler(request, h) {
return { r: "kar" };
},
});
// server.route(routes);
// Serve Catch All Route or Server File with Regex
server.route({
method: "GET",
path: "/{path*}",
options: {
async handler(request, h) {
try {
const total = request.path.match(regex);
if (total) {
return h.file(
process.env.RAZZLE_PUBLIC_DIR + request.path
);
} else {
const context = {};
// Create Redux store, and get initial state.
const store = configureStore({});
const markup = renderToString(
<Provider store={store}>
<StaticRouter
context={context}
location={request.url.pathname}
>
<App />
</StaticRouter>
</Provider>
);
const finalState = store.getState();
// @ts-expect-error
if (context.url) {
// @ts-expect-error
return h.redirect(context.url);
} else {
const helmet = Helmet.renderStatic();
const html =
// prettier-ignore
`<!doctype html>
<html lang="en-us">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charSet='utf-8' />
<meta name="viewport" content="width=device-width, initial-scale=1">
${helmet.title}
${helmet.meta}
<meta name="keywords" content="${CONFIG["keywords"]}">
<meta name="theme-color" content="#ffffff">
<meta property="og:type" content="website" />
<meta property="og:url" content="${CONFIG["domain"]}" />
<meta property="og:site_name" content="${CONFIG["brand"] + ", " + CONFIG["brand_name"]}" />
<meta property="og:image" content="${CONFIG["og"].concat("og.jpg")}" />
<meta property="og:locale" content="en_US" />
${helmet.link.toString()}
<link rel="apple-touch-icon" sizes="57x57" href=${CONFIG["favicon"].concat("apple-icon-57x57.png")}>
<link rel="apple-touch-icon" sizes="60x60" href=${CONFIG["favicon"].concat("apple-icon-60x60.png")}>
<link rel="apple-touch-icon" sizes="72x72" href=${CONFIG["favicon"].concat("apple-icon-72x72.png")}>
<link rel="apple-touch-icon" sizes="76x76" href=${CONFIG["favicon"].concat("apple-icon-76x76.png")}>
<link rel="apple-touch-icon" sizes="114x114" href=${CONFIG["favicon"].concat("apple-icon-114x114.png")}>
<link rel="apple-touch-icon" sizes="120x120" href=${CONFIG["favicon"].concat("apple-icon-120x120.png")}>
<link rel="apple-touch-icon" sizes="144x144" href=${CONFIG["favicon"].concat("apple-icon-144x144.png")}>
<link rel="apple-touch-icon" sizes="152x152" href=${CONFIG["favicon"].concat("apple-icon-152x152.png")}>
<link rel="apple-touch-icon" sizes="180x180" href=${CONFIG["favicon"].concat("apple-icon-180x180.png")}>
<link rel="icon" type="image/png" sizes="192x192" href=${CONFIG["favicon"].concat("android-icon-192x192.png")}>
<link rel="icon" type="image/png" sizes="32x32" href=${CONFIG["favicon"].concat("favicon-32x32.png")}>
<link rel="icon" type="image/png" sizes="96x96" href=${CONFIG["favicon"].concat("favicon-96x96.png")}>
<link rel="icon" type="image/png" sizes="16x16" href=${CONFIG["favicon"].concat("favicon-16x16.png")}>
<link rel="manifest" href=${CONFIG["favicon"].concat("manifest.json")}>
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content=${CONFIG["favicon"].concat("ms-icon-144x144.png")}>
${cssLinksFromAssets(assets, 'client')}
</head>
<body>
<div id="root">${markup}</div>
<script>
window.__PRELOADED_STATE__ = ${serialize(finalState)}
</script>
${jsScriptTagsFromAssets(assets, 'client', ' defer crossorigin')}
</body>
</html>`;
return h.response(html).code(200);
}
}
} catch (err) {
console.log(err);
}
},
},
});
await server.start();
console.log("Server run on %s", server.info.uri);
};
export default ser;
hapi.js is a great Node framework and v17 is fully async/await.
I don't understand all of the inner workings for Razzle, so I am not sure how to configure a hapi server to work properly, but here is a possible starting point that seems to work in place of the Express server:
This seems to work as a drop-in replacement for the Express server code (just copy and paste over the code in the
server.js
file), although I haven't tested it too much.Also, I would like to know if there is a way to change the organization of the files in Razzle? I prefer to separate all of my client and server code into their own folders (e.g., src/client/ and src/server/).
Thank you!