Creating a Minimal Reddit App with Meteor 3 and Blaze

In this tutorial, I'll guide you through creating a simplified version of Reddit as a single-page application using Meteor 3 and Blaze. We'll focus on implementing core functionality like posts and voting without complex routing. For deployment or live demo, please visit https://dev.to/kafechew/a-mini-reddit-app-deployed-to-cloudrun-with-pulumi-esc-iac-meteor-mongodb-atlas-289b. Initial Setup First, let's install Meteor: Install Meteor curl https://install.meteor.com/ | sh After installation, you should see a success message confirming Meteor 3.1.2 has been installed in your home directory. log % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 7869 0 7869 0 0 8837 0 --:--:-- --:--:-- --:--:-- 8831 Downloading Meteor distribution ######################################################################## 100.0% Meteor 3.1.2 has been installed in your home directory (~/.meteor). Writing a launcher script to /usr/local/bin/meteor for your convenience. This may prompt for your password. To get started fast: $ meteor create ~/my_cool_app $ cd ~/my_cool_app $ meteor Or see the docs at: docs.meteor.com Deploy and host your app with Cloud: www.meteor.com/cloud Next, create a new Meteor app with Blaze: meteor create meteor-app --blaze --prototype The --prototype flag includes the autopublish and insecure packages, which are helpful for rapid prototyping. These packages automatically publish all data to the client and allow client-side database modifications without explicit permissions. While convenient for development, they should be removed before deploying to production for security reasons. log Using blaze skeleton Created a new Meteor app in 'meteor-app'. To run your new app: cd meteor-app meteor --port 3001 If you are new to Meteor, try some of the learning resources here: https://www.meteor.com/tutorials When you’re ready to deploy and host your new Meteor application, check out Cloud: https://www.meteor.com/cloud Let's test our new app cd meteor-app meteor --port 3001 log [[[[[ ~/meteor-pulumi-esc/meteor-app ]]]]] => Started proxy. => Started HMR server. => Started MongoDB. => Started your app. => App running at: http://localhost:3001/ Your app should now be running at http://localhost:3001/ Add necessary packages Install the necessary packages for our Reddit clone meteor add accounts-password meteor add accounts-ui meteor add check meteor npm install --save @babel/runtime meteor npm install jquery@1.12.1 These packages provide: User authentication (accounts-password, accounts-ui) Input validation (check) Runtime support for ES6+ features (@babel/runtime) jQuery for DOM manipulation Creating the Data Model Let's set up our data structure. Create a new folder structure imports/api and add a file collections.js. import { Mongo } from 'meteor/mongo'; import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; export const Posts = new Mongo.Collection('posts'); // Define security rules if not using autopublish if (Meteor.isServer) { // Publications Meteor.publish('allPosts', function() { return Posts.find({}, {sort: {votes: -1, createdAt: -1}}); }); } // Methods Meteor.methods({ 'posts.insert'(title, url) { check(title, String); check(url, String); if (!this.userId) { throw new Meteor.Error('not-authorized'); } const user = Meteor.users.findOneAsync(this.userId); const username = user && user.username ? user.username : (user && user.profile && user.profile.name ? user.profile.name : (user && user.emails ? user.emails[0].address : this.userId)); return Posts.insertAsync({ title, url, createdAt: new Date(), userId: this.userId, author: username, votes: 0 }); }, 'posts.upvote'(postId) { check(postId, String); if (!this.userId) { throw new Meteor.Error('not-authorized'); } Posts.updateAsync(postId, {$inc: {votes: 1}}); }, }); This file defines our Posts collection and the methods to interact with it. We've implemented two key methods: posts.insert - Creates a new post with title, URL, and author information posts.upvote - Increments the vote count for a specific post Building the User Interface Replace the content of client/main.html with: Mini Reddit {{> main}} Mini Reddit {{> loginButtons}} {{#if currentUser}} {{> postSubmit}}

Apr 6, 2025 - 05:49
 0
Creating a Minimal Reddit App with Meteor 3 and Blaze

In this tutorial, I'll guide you through creating a simplified version of Reddit as a single-page application using Meteor 3 and Blaze. We'll focus on implementing core functionality like posts and voting without complex routing. For deployment or live demo, please visit https://dev.to/kafechew/a-mini-reddit-app-deployed-to-cloudrun-with-pulumi-esc-iac-meteor-mongodb-atlas-289b.

Initial Setup

First, let's install Meteor:

Install Meteor

curl https://install.meteor.com/ | sh

After installation, you should see a success message confirming Meteor 3.1.2 has been installed in your home directory.

log

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7869    0  7869    0     0   8837      0 --:--:-- --:--:-- --:--:--  8831
Downloading Meteor distribution
######################################################################## 100.0%

Meteor 3.1.2 has been installed in your home directory (~/.meteor).
Writing a launcher script to /usr/local/bin/meteor for your convenience.
This may prompt for your password.

To get started fast:

  $ meteor create ~/my_cool_app
  $ cd ~/my_cool_app
  $ meteor

Or see the docs at:

  docs.meteor.com

Deploy and host your app with Cloud:

  www.meteor.com/cloud

Next, create a new Meteor app with Blaze:

meteor create meteor-app --blaze --prototype

The --prototype flag includes the autopublish and insecure packages, which are helpful for rapid prototyping. These packages automatically publish all data to the client and allow client-side database modifications without explicit permissions. While convenient for development, they should be removed before deploying to production for security reasons.

log

Using blaze skeleton
Created a new Meteor app in 'meteor-app'.                                          

To run your new app:                          
  cd meteor-app                               
  meteor --port 3001                                     

If you are new to Meteor, try some of the learning resources here:
  https://www.meteor.com/tutorials            

When you’re ready to deploy and host your new Meteor application, check out Cloud:
  https://www.meteor.com/cloud  

Let's test our new app

cd meteor-app                               
meteor --port 3001  

log

[[[[[ ~/meteor-pulumi-esc/meteor-app ]]]]]    

=> Started proxy.                             
=> Started HMR server.                        
=> Started MongoDB.                           
=> Started your app.                          

=> App running at: http://localhost:3001/

Your app should now be running at http://localhost:3001/

Add necessary packages

Install the necessary packages for our Reddit clone

meteor add accounts-password
meteor add accounts-ui
meteor add check
meteor npm install --save @babel/runtime
meteor npm install jquery@1.12.1

These packages provide:

  • User authentication (accounts-password, accounts-ui)
  • Input validation (check)
  • Runtime support for ES6+ features (@babel/runtime)
  • jQuery for DOM manipulation

Creating the Data Model

Let's set up our data structure. Create a new folder structure imports/api and add a file collections.js.

import { Mongo } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';

export const Posts = new Mongo.Collection('posts');

// Define security rules if not using autopublish
if (Meteor.isServer) {
  // Publications
  Meteor.publish('allPosts', function() {
    return Posts.find({}, {sort: {votes: -1, createdAt: -1}});
  });
}

// Methods
Meteor.methods({
  'posts.insert'(title, url) {
    check(title, String);
    check(url, String);

    if (!this.userId) {
      throw new Meteor.Error('not-authorized');
    }

    const user = Meteor.users.findOneAsync(this.userId);
    const username = user && user.username ? user.username : 
                    (user && user.profile && user.profile.name ? user.profile.name : 
                    (user && user.emails ? user.emails[0].address : this.userId));

    return Posts.insertAsync({
      title,
      url,
      createdAt: new Date(),
      userId: this.userId,
      author: username,
      votes: 0
    });
  },

  'posts.upvote'(postId) {
    check(postId, String);

    if (!this.userId) {
      throw new Meteor.Error('not-authorized');
    }

    Posts.updateAsync(postId, {$inc: {votes: 1}});
  },
});

This file defines our Posts collection and the methods to interact with it. We've implemented two key methods:

  • posts.insert - Creates a new post with title, URL, and author information
  • posts.upvote - Increments the vote count for a specific post

Building the User Interface

Replace the content of client/main.html with:


  </span>Mini Reddit<span class="nt">
   name="viewport" content="width=device-width, initial-scale=1.0">



  {{> main}}


 name="main">
   class="container">
    

Mini Reddit

class="login">{{> loginButtons}}
{{#if currentUser}} {{> postSubmit}} {{/if}} class="posts"> {{> postsList}}