0

How can deploy quasar v2 ssr application into firebase-functions?

In v1, it can be done by following step:

First, I insert code at bottom in src-ssr/index.js file:

const functions=require("firebase-functions"); exports.samplefun=functions.https.onRequest(app);

But in new version, there are no file "index.js" in src-ssr directory.

Please help me to resolve the problem.

2 Answers 2

1

Quasar v2 has replaced the index.js file with file(s) called "middleware." Here's the URL where they talk about it: Quasar v2 SSR Upgrade Guide.

I made a full working repo and explanation that will get you going: https://github.com/l1qu1d/quasar-v2-ssr-firebase

Sign up to request clarification or add additional context in comments.

7 Comments

Your last edit turned your answer into a link-only post, which would risk being flagged as "not an answer" and being deleted. I undid that. You can add a link, but the essential answer should still be available directly here.
@Yunnosch Thanks for that. I agree the answer should be put on here but it's not a simple fix as it requires a LOT of context for someone that is just starting to look at this problem. I just spent the last hour working on my repo and I'm not going to rewrite it all on here.
The reason for it being at the top was so that people didn't have to read everything and could just get to the point. But since I'm new at this, I just decided to clean up the information that isn't relevant, thus achieving the goal.
It answers the question & gets straight to the point! Users want direct useful information. The code example had nothing to do with his question as it was me explaining my thought process on what I thought could be the problem --which it was not. The links are supplemental as I answer the question. The original poster has no clue what happened to index.js. I say why and give a link. You don't have the background nor context on what we're trying to achieve but, in your opinion, you say that I "have now removed most of the information which made a decent answer." You want complexity. I do not.
There is no point in adding content on here when the work has already been written somewhere else. Clearly, the links are not spam and I say exactly what it is. Why would someone, like me, go through all this hassle with back and forth to make spam?! If they do, that's on them and me, of which, I'll risk it. Copying long complex solutions for the sake of just having it on here is nonsensical.
|
0

The solution above doesn't work for me with the new version of quasar V2.

Here my src-ssr/server.ts file :

    import { RenderError } from '@quasar/app-vite';
    import { ssrMiddleware } from 'quasar/wrappers';
    
    export default ssrMiddleware(({ app, resolve, render, serve }) => {
      // we capture any other Express route and hand it
      // over to Vue and Vue Router to render our page
      app.get(resolve.urlPath('*'), (req, res) => {
        res.setHeader('Content-Type', 'text/html');
    
        render(/* the ssrContext: */ { req, res })
          .then((html) => {
            // now let's send the rendered html to the client
            res.send(html);
          })
          .catch((err: RenderError) => {
            // oops, we had an error while rendering the page
    
            // we were told to redirect to another URL
            if (err.url) {
              if (err.code) {
                res.redirect(err.code, err.url);
              } else {
                res.redirect(err.url);
              }
            } else if (err.code === 404) {
              // hmm, Vue Router could not find the requested route
    
              // Should reach here only if no "catch-all" route
              // is defined in /src/routes
              res.status(404).send('404 | Page Not Found');
            } else if (process.env.DEV) {
              // well, we treat any other code as error;
              // if we're in dev mode, then we can use Quasar CLI
              // to display a nice error page that contains the stack
              // and other useful information
    
              // serve.error is available on dev only
              serve.error({ err, req, res });
            } else {
              // we're in production, so we should have another method
              // to display something to the client when we encounter an error
              // (for security reasons, it's not ok to display the same wealth
              // of information as we do in development)
    
              // Render Error Page on production or
              // create a route (/src/routes) for an error page and redirect to it
              res.status(500).send('500 | Internal Server Error');
              // console.error(err.stack)
            }
          });
      });
    });

Here my src-ssr/middlewares/render.ts file :

/**
 * More info about this file:
 * https://v2.quasar.dev/quasar-cli-vite/developing-ssr/ssr-webserver
 *
 * Runs in Node context.
 */

/**
 * Make sure to yarn add / npm install (in your project root)
 * anything you import here (except for express and compression).
 */
import express from 'express';
import compression from 'compression';
// const functions = require('firebase-functions')
// import functions from 'firebase-functions'

import {
  ssrClose,
  ssrCreate,
  ssrListen,
  ssrRenderPreloadTag,
  ssrServeStaticContent,
} from 'quasar/wrappers';

/**
 * Create your webserver and return its instance.
 * If needed, prepare your webserver to receive
 * connect-like middlewares.
 *
 * Should NOT be async!
 */
export const create = ssrCreate((/* { ... } */) => {
  const app = express();

  // attackers can use this header to detect apps running Express
  // and then launch specifically-targeted attacks
  app.disable('x-powered-by');

  // place here any middlewares that
  // absolutely need to run before anything else
  if (process.env.PROD) {
    app.use(compression());
  }

  return app;
});

/**
 * You need to make the server listen to the indicated port
 * and return the listening instance or whatever you need to
 * close the server with.
 *
 * The "listenResult" param for the "close()" definition below
 * is what you return here.
 *
 * For production, you can instead export your
 * handler for serverless use or whatever else fits your needs.
 */
export const listen = ssrListen(async ({ app, port, isReady }) => {
  await isReady();
  return app.listen(port, () => {
    if (process.env.PROD) {
      console.log('Server listening at port ' + port);
    }
  });
});

/**
 * Should close the server and free up any resources.
 * Will be used on development only when the server needs
 * to be rebooted.
 *
 * Should you need the result of the "listen()" call above,
 * you can use the "listenResult" param.
 *
 * Can be async.
 */
export const close = ssrClose(({ listenResult }) => {
  return listenResult.close();
});

const maxAge = process.env.DEV ? 0 : 1000 * 60 * 60 * 24 * 30;

/**
 * Should return middleware that serves the indicated path
 * with static content.
 */
export const serveStaticContent = ssrServeStaticContent((path, opts) => {
  return express.static(path, {
    maxAge,
    ...opts,
  });
});

const jsRE = /\.js$/;
const cssRE = /\.css$/;
const woffRE = /\.woff$/;
const woff2RE = /\.woff2$/;
const gifRE = /\.gif$/;
const jpgRE = /\.jpe?g$/;
const pngRE = /\.png$/;

/**
 * Should return a String with HTML output
 * (if any) for preloading indicated file
 */
export const renderPreloadTag = ssrRenderPreloadTag((file) => {
  if (jsRE.test(file) === true) {
    return `<link rel="modulepreload" href="${file}" crossorigin>`;
  }

  if (cssRE.test(file) === true) {
    return `<link rel="stylesheet" href="${file}">`;
  }

  if (woffRE.test(file) === true) {
    return `<link rel="preload" href="${file}" as="font" type="font/woff" crossorigin>`;
  }

  if (woff2RE.test(file) === true) {
    return `<link rel="preload" href="${file}" as="font" type="font/woff2" crossorigin>`;
  }

  if (gifRE.test(file) === true) {
    return `<link rel="preload" href="${file}" as="image" type="image/gif">`;
  }

  if (jpgRE.test(file) === true) {
    return `<link rel="preload" href="${file}" as="image" type="image/jpeg">`;
  }

  if (pngRE.test(file) === true) {
    return `<link rel="preload" href="${file}" as="image" type="image/png">`;
  }

  return '';
});

My question is : 1- How to configure the rewrites object in firebase.json 2- how to configure firebase to use the ssr from quasar js

I'm really surprised that it's such a misery to do ssr at a time when google referencing is the norm.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.