Server-side integration with Express.js and template engines
Try the Node.js/Express integration in action:
npm install modern-toasts express
// server.js
const express = require('express');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3000;
// Serve static files
app.use(express.static('public'));
app.use('/modern-toasts', express.static(
path.join(__dirname, 'node_modules/modern-toasts/dist')
));
// Parse JSON bodies
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Basic route with toast integration
app.get('/', (req, res) => {
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>ModernToasts + Express</title>
<script src="/modern-toasts/modern-toasts.min.js"></script>
</head>
<body>
<h1>Welcome to Express + ModernToasts!</h1>
<button onclick="showWelcome()">Show Welcome Toast</button>
<script>
const { toast } = window.ModernToasts;
function showWelcome() {
toast.success('Welcome to our Express app!');
}
</script>
</body>
</html>
`);
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
// routes/api.js
const express = require('express');
const router = express.Router();
// User registration endpoint
router.post('/register', async (req, res) => {
try {
const { email, password } = req.body;
// Validation
if (!email || !password) {
return res.status(400).json({
success: false,
message: 'Email and password are required',
toastType: 'error'
});
}
// Simulate user creation
const user = await createUser({ email, password });
res.json({
success: true,
message: 'Account created successfully!',
toastType: 'success',
user: { id: user.id, email: user.email }
});
} catch (error) {
res.status(500).json({
success: false,
message: 'Server error. Please try again.',
toastType: 'error'
});
}
});
// Login endpoint
router.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
const user = await authenticateUser(email, password);
if (!user) {
return res.status(401).json({
success: false,
message: 'Invalid credentials',
toastType: 'error'
});
}
res.json({
success: true,
message: `Welcome back, ${user.name}!`,
toastType: 'success',
token: generateToken(user.id)
});
} catch (error) {
res.status(500).json({
success: false,
message: 'Login failed. Please try again.',
toastType: 'error'
});
}
});
module.exports = router;
// public/js/api.js
class ApiClient {
constructor() {
this.baseURL = '/api';
}
async request(endpoint, options = {}) {
try {
const response = await fetch(`${this.baseURL}${endpoint}`, {
headers: {
'Content-Type': 'application/json',
...options.headers
},
...options
});
const data = await response.json();
// Show toast based on response
if (data.toastType && data.message) {
toast[data.toastType](data.message);
}
if (!response.ok) {
throw new Error(data.message || 'Request failed');
}
return data;
} catch (error) {
toast.error(error.message || 'Network error occurred');
throw error;
}
}
async register(userData) {
return this.request('/register', {
method: 'POST',
body: JSON.stringify(userData)
});
}
async login(credentials) {
return this.request('/login', {
method: 'POST',
body: JSON.stringify(credentials)
});
}
}
// middleware/toast.js
const toastMiddleware = (req, res, next) => {
// Add toast helper methods to response
res.toast = {
success: (message, options = {}) => {
res.locals.toast = {
type: 'success',
message,
options
};
},
error: (message, options = {}) => {
res.locals.toast = {
type: 'error',
message,
options
};
},
info: (message, options = {}) => {
res.locals.toast = {
type: 'info',
message,
options
};
},
warning: (message, options = {}) => {
res.locals.toast = {
type: 'warning',
message,
options
};
}
};
next();
};
module.exports = toastMiddleware;
// Use the middleware
app.use(toastMiddleware);
app.post('/contact', (req, res) => {
const { name, email, message } = req.body;
if (!name || !email || !message) {
res.toast.error('All fields are required');
return res.redirect('/contact');
}
// Process contact form
sendContactEmail({ name, email, message });
res.toast.success('Message sent successfully!');
res.redirect('/contact');
});
<!-- views/layout.ejs -->
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<script src="/modern-toasts/modern-toasts.min.js"></script>
</head>
<body>
<%- body %>
<script>
const { toast } = window.ModernToasts;
// Configure toast
toast.configure({
position: 'top-right',
maxVisibleStackToasts: 3
});
// Show toast if one is set
<% if (locals.toast) { %>
toast.<%= toast.type %>('<%= toast.message %>', <%- JSON.stringify(toast.options) %>);
<% } %>
</script>
</body>
</html>
<!-- views/layouts/main.hbs -->
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<script src="/modern-toasts/modern-toasts.min.js"></script>
</head>
<body>
{{{body}}}
<script>
const { toast } = window.ModernToasts;
{{#if toast}}
toast.{{toast.type}}('{{{toast.message}}}', {{{json toast.options}}});
{{/if}}
</script>
</body>
</html>
// routes/upload.js
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
router.post('/upload', upload.single('file'), (req, res) => {
if (!req.file) {
return res.status(400).json({
success: false,
message: 'No file uploaded',
toastType: 'error'
});
}
// Process file
processFile(req.file)
.then(() => {
res.json({
success: true,
message: `File "${req.file.originalname}" uploaded successfully!`,
toastType: 'success'
});
})
.catch(() => {
res.status(500).json({
success: false,
message: 'File processing failed',
toastType: 'error'
});
});
});
// routes/users.js
router.put('/users/:id', async (req, res) => {
try {
const { id } = req.params;
const updates = req.body;
const user = await User.findByIdAndUpdate(id, updates, { new: true });
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found',
toastType: 'error'
});
}
res.json({
success: true,
message: 'Profile updated successfully!',
toastType: 'success',
user
});
} catch (error) {
if (error.code === 11000) {
res.status(400).json({
success: false,
message: 'Email already exists',
toastType: 'error'
});
} else {
res.status(500).json({
success: false,
message: 'Update failed. Please try again.',
toastType: 'error'
});
}
}
});