Skip to content

Instantly share code, notes, and snippets.

@ggorlen
Last active July 17, 2024 14:21
Show Gist options
  • Save ggorlen/8eccfe543a74717b13703cf7a2e03679 to your computer and use it in GitHub Desktop.
Save ggorlen/8eccfe543a74717b13703cf7a2e03679 to your computer and use it in GitHub Desktop.
Today I learned

Random tidbits

d3.js SVG exports have quirky stylesheet issues

Exporting a SVG from a d3 graphic led to issues with a missing stylesheet. See this comment for a workaround I used (adding .attr("style", ...) to inline the styles onto each node), and the accompanying thread for some of the quirks, like the allowed CSS selector names.

Vue allows arrays of composables (but VueQuery doesn't like it)

I don't think arrays of hooks are possible in React 18, but it is (apparently) OK to do arrays of composables in Vue 3:

<!doctype html>
<html lang="en">
<body>
<div id="app">
  <button @click="newConversation()">
    New Conversation
  </button>
  <div v-for="(conversation, index) in conversations" :key="index">
    <h3>Conversation {{ index + 1 }}</h3>
    <ul>
      <li v-for="(message, index) in conversation.messages" :key="index">{{ message }}</li>
    </ul>
    <button @click="addMessageToConversation(index, 'new message')">
      Add Message to Conversation {{ index + 1 }}
    </button>
  </div>
</div>
<script src="https://unpkg.com/vue@3.4.31/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tanstack/vue-query@4.19.1/build/umd/index.production.min.js"></script>
<script>
const useConversation = () => {
  const messages = Vue.ref([]);
  //const queryInfo = VueQuery.useQuery("example", () =>
  //  fetch("https://jsonplaceholder.typicode.com/todos/1")
  //    .then(res => res.json())
  //);

  const addMessage = (newMessage) => {
    messages.value.push(newMessage);
  };

  return { messages, addMessage };
};

const app = Vue.createApp({
  setup() {
    const conversations = Vue.ref([useConversation(), useConversation()]);

    const newConversation = () => {
      conversations.value.push(useConversation());
    };

    const addMessageToConversation = (index, newMessage) => {
      conversations.value[index].addMessage(newMessage);
    };

    return { conversations, addMessageToConversation, newConversation };
  },
});
app.use(VueQuery.VueQueryPlugin);
app.mount("#app");
</script>
</body>
</html>

The problem is, VueQuery throws Error: vue-query hooks can only be used inside setup() function if you uncomment the commented-out useQuery call in the above snippet.

Vue nested click handlers bubble

Consider this code:

<div
  v-for="question in questions"
  @click="switchToQuestion(question)"
>
  <button @click="deleteQuestion(question)">
    Delete
  </button>
</div>

I ran into a bug where clicking the Delete button caused the switchToQuestion() handler to be triggered, resulting in switching to an already-deleted question. The solution is to use @click.stop on the inner click handler to prevent bubbling.

nginx try_files incorrectly using .html files as fallback for .js scripts and static assets

Consider this nginx block:

location ~* ^/(foobar)/.*\.(?:css|js|png|jpe?g|gif|ico|svg|eot|ttf|woff2?)$ {
    expires 365d;
    add_header Pragma public;
    add_header Cache-Control "public, must-revalidate, proxy-revalidate";
    access_log off;
    try_files $uri /$uri.html $1 /index.html =404;
}

This led to a super annoying caching problem where during deployment, the JS files might not be served properly and wind up serving the SPA's index.html instead of a JS script, which would throw an error Uncaught SyntaxError: expected expression, got '<' then be cached for a year, causing the app to fail.

The solution was getting those .html files out of the try_files line: try_files $1 $uri =404;.

App running but no pages load in Dockerized Vite (Vue) app

Per this comment, use

{
  server: {
    host: '0.0.0.0'
  }
}

in vite.config.js.

ERR_CERT_DATE_INVALID on DigitalOcean droplet with GoDaddy-issued domain

Previously working, abruptly not with the titular error. I tried certbot -q renew --nginx but ran into an error that the .pem files weren't found. I noticed in /etc/nginx/sites-available/my-site that there was a number of incorrect paths to /etc/letsencrypt/live/my-domain.com/ (for example, ssl_certificate /etc/letsencrypt/live/wrong-domain.com/fullchain.pem). nginx -t failed to validate the path. After fixing the config paths to point to the correct domain and re-running certbot, the certificate was renewed and nginx -t ran clean.

I'm not sure how the bad links got into the nginx config in the first place, though, or why this config only suddenly started to matter, since the site worked fine for over a year without intervention (other than a domain name renewal nearly 90 days ago, but not quite--might be related).

I may need a cron job to auto-renew.

Server-sent events arriving as a batch on Nginx

Adding proxy_buffering off; to the http section in /etc/nginx/nginx.conf and running sudo systemctl restart nginx worked for my Flask app running in a DigitalOcean Droplet.

See EventSource / Server-Sent Events through Nginx and Server-Sent Events in Flask work locally but not on production (linode).

Running a C program as an executable

./execute_me.c -> hello world:

#if 0
# https://news.ycombinator.com/item?id=39272890
set -e; [ "$0" -nt "$0.bin" ] &&
gcc -Wall -Wextra -pedantic -std=c99 "$0" -o "$0.bin"
exec "$0.bin" "$@"
#endif

#include <stdio.h>

int main() {
    puts("hello world");
    return 0;
}

git grep

git grep -i pattern basically greps the way I want to, respecting .gitignore.

I can replace alias g="grep -RiP --exclude-dir={node_modules,.git,build,dist}" with alias g="git grep -i".

Auth0 + React blank screen: bad .env credentials

In auth0 with React, if the app gives a blank screen, it could be because of bad Auth0 .env credentials.

mpv works with URLs!

I had logic in a discogs userscript to extract youtube video links for playing with mpv, but it turns out mpv -no-vid https://www.discogs.com/master/27848-Amon-D%C3%BC%C3%BCl-Paradiesw%C3%A4rts-D%C3%BC%C3%BCl works just fine, as do many other URLs (like Bandcamp artists and albums).

Getting rid of annoying terminal start messages

Every new bash terminal window in Ubuntu gave

Command 'ng' not found, but can be installed with:
sudo apt install ng-common
greg@greg-framework:~$ 

upon opening. This occurred after upgrading Node 18 to 20 with nvm. The fix was removing

# Load Angular CLI autocompletion.
source <(ng completion script)

from ~/.bashrc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment