Thanks you for a great tutorial! 
For people rocking the latest version of Strapi, here’s a things to note.
bootstrap.js
socket.io should be implemented like this:
// Socket io for live refresh
process.nextTick(() => {
var io = require("socket.io")(strapi.server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
});
console.log(strapi.server); //workss
io.on("connection", async function (socket) {
console.log(`a user connected`);
// send message on user connection
socket.emit(
"hello",
{ message: "Welcome to my website" }
);
// listen for user diconnect
socket.on("disconnect", () => {
console.log("a user disconnected");
});
});
strapi.io = io; // register socket io inside strapi main object to use it globally anywhere
});
Also if you’re rocking Strapi in docker (the default example stack), modules can be installed with.
docker container exec -it strapiexample /bin/bash
npm install socket.io
Also… In React 6 Switches
are now Routes
, so you should do a implementation like this.
import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Home from "./components/Home";
import ProductDetail from "./components/ProductDetail";
// other imports
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
export default function App() {
return (
<Router>
<ToastContainer />
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/:product_id" element={<ProductDetail />} />
...
</Routes>
</Router>
);
}
It’s also a good practice to use key
values for every looped elements like this in Home.js
. Fell free to fix it in other files, too.
...
export default function Home() {
const [products, setProducts] = useState([]);
...
return (
<div className="container">
<h1>Products</h1>
<div className="products-container">
{products.map((product) => (
<Link
className="product"
to={`/${product.id}`}
key={`/${product.id}`}
>
<img src={`http://localhost:1337${product.images[0].url}`} />
<h2 className="product-name">{product.name}</h2>
<p className="product-desc">{product.description}</p>
</Link>
))}
</div>
</div>
);
}
I also mistypes it and created it as image
instead of images
… Spotted the mistake by looking at the response from the backend.