Several customers have approached us and asked how they can create a Google Docs like web app using our APIs. [Google Docs][1] is a word processor that allows users to create and edit files online while collaborating with other users in real-time.

This blog post explains how easy it is to create a lite version of Google Docs that has the following features:

  • Rich Text Editing (change text font, size, colour, style (boldface, italic), alignment etc.).
  • Real-time collaborative editing of the same document. Multiple users can access the document at the same time and modify it.
  • Upload content of an existing Word Document into an editor.
  • Save text in the editor as MS Word, PDF, TXT or HTML document.

Our end product will look as follows:

Google Docs like App Interface
  • [Tools and Technologies][2]
  • [Integrate Firepad][3]
  • [Upload Content of an Existing Word Document into an Editor][4]
  • [Integrate GroupDocs.Editor][5]
  • [Form Data Handling][6]

Tools and Technologies – Create Google Docs like App

We will develop the Google Docs like web app in ASP.NET Core and use the following two libraries:

  • [Firepad][7] is an open-source, collaborative text editor. It uses the [Firebase][8] Realtime Database as a backend so it requires no server-side code and can be added to any web app simply by including the JavaScript files.
  • [GroupDocs.Editor for .NET][9] gives us an ability to edit most popular document formats using any [WYSIWYG][10] editor without any additional applications. We will load document via GroupDocs.Editor into Firepad, edit document in a way we want and save it back to original document format.

I have used [Visual Studio for Mac][11] as an [IDE][12]. However, you can download the free community edition of Visual Studio, depending upon your platform, from [here][13]. Let’s start.

Create a new ASP.NET Core Web Application project and name the project “GoogleDocsLite”.

Create a new ASP.NET Core Web App

Run the application to ensure everything is set up properly.

Integrate Firepad

We can add Firepad to our web app by including the following JavaScript files in the section of _Layout.cshtml.

<!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/7.13.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.13.2/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.13.2/firebase-database.js"></script>

<!-- CodeMirror -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.17.0/codemirror.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.17.0/codemirror.css" />

<!-- Firepad -->
<link rel="stylesheet" href="https://firepad.io/releases/v1.5.9/firepad.css" />
<script src="https://firepad.io/releases/v1.5.9/firepad.min.js"></script>

<!-- userlist -->
<script src="~/js/firepad-userlist.js"></script>
<link rel="stylesheet" href="~/css/firepad-userlist.css" />

To create a Firepad, we will initialize Firebase, CodeMirror and then Firepad. Add the following script and HTML code in Index.cshtml.

<script>
    function init() {
        // Initialize Firebase.
        // TODO: replace with your Firebase project configuration.
        var config = {
            apiKey: '',
            authDomain: "",
            databaseURL: ""
        };
        firebase.initializeApp(config);
        
        // Get Firebase Database reference.
        var firepadRef = getExampleRef();
        
        // Create CodeMirror (with lineWrapping on).
        var codeMirror = CodeMirror(document.getElementById('firepad'), { lineWrapping: true });

        // Create a random ID to use as our user ID (we must give this to firepad and FirepadUserList).
        var userId = Math.floor(Math.random() * 9999999999).toString();

        // Create Firepad (with rich text features and our desired userId).
        var firepad = Firepad.fromCodeMirror(firepadRef, codeMirror,
                    { richTextToolbar: true, richTextShortcuts: true, userId: userId });

        // Create FirepadUserList (with our desired userId).
        var firepadUserList = FirepadUserList.fromDiv(firepadRef.child('users'),
        document.getElementById('userlist'), userId);
    }
    
    // Helper to get hash from end of URL or generate a random one.
    function getExampleRef() {
        var ref = firebase.database().ref();
        var hash = window.location.hash.replace(/#/g, '');
        if (hash) {
            ref = ref.child(hash);
        } else {
            ref = ref.push(); // generate unique location.
            window.location = window.location + '#' + ref.key; // add it as a hash to the URL.
        }
        if (typeof console !== 'undefined') {
            console.log('Firebase data: ', ref.toString());
        }
        return ref;
    }
</script>

<div id="userlist"></div>
<div id="firepad"></div>

Please replace the contents of config with your own Firebase project’s config.

We want the script to run after the page loads completely. Call init() from the onload attribute of the element in _Layout.cshtml.

<body onload="init()">

Your <body> element should look as follows. Remove any unnecessary tags such as <header> or <footer>.

Body Element

If you run the project, you will notice that firepad and userlist are not aligned properly. Add the following CSS to adjust their size and position. Place it inside the of _Layout.cshtml.

<style>
    html {
        height: 100%;
    }

    body {
        margin: 0;
        height: 100%;
    }

    /* We make the user list 175px and firepad fill the rest of the page. */
    #userlist {
        position: absolute;
        left: 0;
        top: 50px;
        bottom: 0;
        height: auto;
        width: 175px;
    }

    #firepad {
        position: absolute;
        left: 175px;
        top: 50px;
        bottom: 0;
        right: 0;
        height: auto;
    }
</style>

Firepad has been successfully set up.

Upload Content of an Existing Word Document into an Editor

Now we want to let users upload a Word document and see its content in the editor. On the front end, add an element of type file. On the back end, use the [GroupDocs.Editor][9] library to convert the Word document to an HTML string, then display it with Firepad’s setHtml() method.

Add the following element in Index.cshtml before the tag.

<form method="post" enctype="multipart/form-data" id="uploadForm">
    <input asp-for="UploadedDocument" />
    <input type="submit" value="Upload Document" class="btn btn-primary" asp-page-handler="UploadDocument" />
</form>

In Index.cshtml.cs, define a matching property.

[BindProperty]
public IFormFile UploadedDocument { get;  set; }

Run the project and click Choose file. Select a Word document and click Upload Document. Nothing happens yet because we still need a handler and the GroupDocs.Editor library.

Integrate GroupDocs.Editor

GroupDocs.Editor is available as a NuGet package. Right‑click the project, choose Manage NuGet Packages, search for GroupDocs.Editor, and click Add Package.

Add GroupDocs.Editor via NuGet Package Manager

After installation, the package appears under the NuGet subfolder in Dependencies.

Form Data Handling

Create a handler (OnPostUploadDocument()) that runs when the user clicks Upload Document. The UploadedDocument (type IFormFile) contains the file data. Save the file, then use GroupDocs.Editor to read its content as HTML.

private readonly IWebHostEnvironment _hostingEnvironment;

public string DocumentContent { get; set