├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── docs ├── content │ ├── en │ │ ├── index.md │ │ ├── options.md │ │ ├── setup.md │ │ └── usage │ │ │ └── useSocialTags.md │ └── settings.json ├── nuxt.config.js ├── package.json ├── static │ ├── favicon.ico │ ├── icon.png │ ├── logo-dark.svg │ ├── logo-light.svg │ └── sw.js ├── tailwind.config.js └── yarn.lock ├── package.json ├── playground ├── app.vue ├── nuxt.config.ts └── package.json ├── renovate.json ├── src ├── module.ts └── runtime │ ├── composables │ └── useSocialTags.ts │ └── plugin.ts ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_size = 2 5 | indent_style = space 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@nuxtjs/eslint-config-typescript" 4 | ], 5 | "rules": { 6 | "@typescript-eslint/no-unused-vars": [ 7 | "off" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules 3 | 4 | # Logs 5 | *.log* 6 | 7 | # Temp directories 8 | .temp 9 | .tmp 10 | .cache 11 | 12 | # Yarn 13 | **/.yarn/cache 14 | **/.yarn/*state* 15 | 16 | # Generated dirs 17 | dist 18 | 19 | # Nuxt 20 | .nuxt 21 | .output 22 | .vercel_build_output 23 | .build-* 24 | .env 25 | .netlify 26 | 27 | # Env 28 | .env 29 | 30 | # Testing 31 | reports 32 | coverage 33 | *.lcov 34 | .nyc_output 35 | 36 | # VSCode 37 | .vscode 38 | 39 | # Intellij idea 40 | *.iml 41 | .idea 42 | 43 | # OSX 44 | .DS_Store 45 | .AppleDouble 46 | .LSOverride 47 | .AppleDB 48 | .AppleDesktop 49 | Network Trash Folder 50 | Temporary Items 51 | .apdisk 52 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [1.2.3](https://github.com/intevel/nuxt-social-tags/compare/v1.2.2...v1.2.3) (2022-09-04) 6 | 7 | 8 | ### Bug Fixes 9 | 10 | * **module:** compatibilty issue ([64ea95d](https://github.com/intevel/nuxt-social-tags/commit/64ea95d4ae903b689b3fa135ea7f80e3ffb8c518)) 11 | 12 | ### [1.2.2](https://github.com/intevel/nuxt-social-tags/compare/v1.2.1...v1.2.2) (2022-04-23) 13 | 14 | 15 | ### Bug Fixes 16 | 17 | * **docs:** readme badges removed ([a6976b1](https://github.com/intevel/nuxt-social-tags/commit/a6976b14f9bf2361e3bad83336d6cfa181eb92b8)) 18 | 19 | ### [1.2.1](https://github.com/intevel/nuxt-directus/compare/v1.2.0...v1.2.1) (2022-04-10) 20 | 21 | 22 | ### Bug Fixes 23 | 24 | * OpenGraph can't be override ([f323fca](https://github.com/intevel/nuxt-directus/commit/f323fca14d23339a84cc022fb21ed16c5ab666c3)), closes [#2](https://github.com/intevel/nuxt-directus/issues/2) 25 | 26 | ## [1.2.0](https://github.com/intevel/nuxt-directus/compare/v1.1.1...v1.2.0) (2022-04-10) 27 | 28 | 29 | ### Features 30 | 31 | * added twitter_card support ([305c4b0](https://github.com/intevel/nuxt-directus/commit/305c4b06cda6ca675d89b6d3eee0856392e586d5)) 32 | 33 | ### [1.1.1](https://github.com/Intevel/nuxt-tags/compare/v1.1.0...v1.1.1) (2022-04-09) 34 | 35 | ## 1.1.0 (2022-04-09) 36 | 37 | 38 | ### Features 39 | 40 | * add composable for updating ([8bdb852](https://github.com/Intevel/nuxt-tags/commit/8bdb85244ec5e9dd8e29537a97f5cbe7b5dab1ec)) 41 | 42 | 43 | ### Bug Fixes 44 | 45 | * rename in setup docs ([f2e350f](https://github.com/Intevel/nuxt-tags/commit/f2e350fb07126a38863a9793eb0a9ab702c610f4)) 46 | * renamed module ([3690ca2](https://github.com/Intevel/nuxt-tags/commit/3690ca22d55f8040790d00c38cc27157d9172546)) 47 | * updated module name ([66aa8d3](https://github.com/Intevel/nuxt-tags/commit/66aa8d36a158db8a15b73afee66cf4cf3f31b1df)) 48 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, caste, color, religion, or sexual 10 | identity and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or advances of 31 | any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email address, 35 | without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at github@conner-bachmann.de. 63 | All complaints will be reviewed and investigated promptly and fairly. 64 | 65 | All community leaders are obligated to respect the privacy and security of the 66 | reporter of any incident. 67 | 68 | ## Enforcement Guidelines 69 | 70 | Community leaders will follow these Community Impact Guidelines in determining 71 | the consequences for any action they deem in violation of this Code of Conduct: 72 | 73 | ### 1. Correction 74 | 75 | **Community Impact**: Use of inappropriate language or other behavior deemed 76 | unprofessional or unwelcome in the community. 77 | 78 | **Consequence**: A private, written warning from community leaders, providing 79 | clarity around the nature of the violation and an explanation of why the 80 | behavior was inappropriate. A public apology may be requested. 81 | 82 | ### 2. Warning 83 | 84 | **Community Impact**: A violation through a single incident or series of 85 | actions. 86 | 87 | **Consequence**: A warning with consequences for continued behavior. No 88 | interaction with the people involved, including unsolicited interaction with 89 | those enforcing the Code of Conduct, for a specified period of time. This 90 | includes avoiding interactions in community spaces as well as external channels 91 | like social media. Violating these terms may lead to a temporary or permanent 92 | ban. 93 | 94 | ### 3. Temporary Ban 95 | 96 | **Community Impact**: A serious violation of community standards, including 97 | sustained inappropriate behavior. 98 | 99 | **Consequence**: A temporary ban from any sort of interaction or public 100 | communication with the community for a specified period of time. No public or 101 | private interaction with the people involved, including unsolicited interaction 102 | with those enforcing the Code of Conduct, is allowed during this period. 103 | Violating these terms may lead to a permanent ban. 104 | 105 | ### 4. Permanent Ban 106 | 107 | **Community Impact**: Demonstrating a pattern of violation of community 108 | standards, including sustained inappropriate behavior, harassment of an 109 | individual, or aggression toward or disparagement of classes of individuals. 110 | 111 | **Consequence**: A permanent ban from any sort of public interaction within the 112 | community. 113 | 114 | ## Attribution 115 | 116 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 117 | version 2.1, available at 118 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 119 | 120 | Community Impact Guidelines were inspired by 121 | [Mozilla's code of conduct enforcement ladder][mozilla coc]. 122 | 123 | For answers to common questions about this code of conduct, see the FAQ at 124 | [https://www.contributor-covenant.org/faq][faq]. Translations are available at 125 | [https://www.contributor-covenant.org/translations][translations]. 126 | 127 | [homepage]: https://www.contributor-covenant.org 128 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 129 | [mozilla coc]: https://github.com/mozilla/diversity 130 | [faq]: https://www.contributor-covenant.org/faq 131 | [translations]: https://www.contributor-covenant.org/translations -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Conner Luka Bachmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nuxt-social-tags 2 | 3 | [![npm version][npm-version-src]][npm-version-href] 4 | [![npm downloads][npm-downloads-src]][npm-downloads-href] 5 | [![License][license-src]][license-href] 6 | 7 | > Easy generation of OpenGraph & Twitter meta-tags in [Nuxt 3](https://v3.nuxtjs.org) 8 | 9 | - [✨  Release Notes](https://github.com/intevel/nuxt-social-tags/releases) 10 | - [📖  Read the documentation](https://nuxt-social-tags.netlify.app/) 11 | 12 | ## Features 13 | 14 | - Nuxt3 ready 15 | - Composables 16 | - Simple Usage 17 | - TypeScript Support 18 | 19 | ## Setup 20 | 21 | ```sh 22 | yarn add nuxt-social-tags # yarn 23 | npm i nuxt-social-tags # npm 24 | ``` 25 | 26 | ## Basic usage 27 | 28 | Add `nuxt-social-tags` to your Nuxt config: 29 | 30 | ```javascript 31 | // nuxt.config 32 | export default { 33 | modules: ["nuxt-social-tags"], 34 | }; 35 | ``` 36 | 37 | ## Development 38 | 39 | 1. Clone this repository 40 | 2. Install dependencies using `yarn install` or `npm install` 41 | 3. Start development server using `yarn dev` or `npm run dev` 42 | 43 | ## License 44 | 45 | Copyright (c) 2022 Conner Luka Bachmann 46 | [MIT License](./LICENSE) 47 | 48 | 49 | 50 | [npm-version-src]: https://img.shields.io/npm/v/nuxt-social-tags/latest.svg 51 | [npm-version-href]: https://npmjs.com/package/nuxt-social-tags 52 | [npm-downloads-src]: https://img.shields.io/npm/dt/nuxt-social-tags.svg 53 | [npm-downloads-href]: https://npmjs.com/package/nuxt-social-tags 54 | [github-actions-ci-src]: https://github.com/intevel/nuxt-social-tags/actions/workflows/ci.yml/badge.svg 55 | [github-actions-ci-href]: https://github.com/intevel/nuxt-social-tags/actions?query=workflow%3Aci 56 | [codecov-src]: https://img.shields.io/codecov/c/github/intevel/nuxt-social-tags.svg 57 | [codecov-href]: https://codecov.io/gh/intevel/nuxt-social-tags 58 | [license-src]: https://img.shields.io/npm/l/nuxt-social-tags.svg 59 | [license-href]: https://npmjs.com/package/nuxt-social-tags 60 | -------------------------------------------------------------------------------- /docs/content/en/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Introduction" 3 | description: "Easy generation of OpenGraph & Twitter meta-tags in Nuxt 3" 4 | position: 1 5 | category: "" 6 | menuTitle: "Introduction" 7 | features: 8 | - Nuxt3 ready 9 | - Composables 10 | - Simple Usage 11 | - TypeScript Support 12 | --- 13 | 14 | Easy generation of OpenGraph & Twitter meta-tags in [Nuxt 3](https://nuxt.com/). 15 | 16 | ## Features 17 | 18 | 19 | 20 | ## Links 21 | 22 | - [GitHub](https://github.com/intevel/nuxt-social-tags) 23 | - [Release Notes](/releases) 24 | 25 | 26 | 27 | To get started head to [Setup](/setup) section. 28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/content/en/options.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Options" 3 | description: "Discover the available options to configure" 4 | position: 4 5 | category: "Getting started" 6 | --- 7 | 8 | All options are optional, the module will generate meta tags from the provided options. 9 | 10 | ### `enabled` 11 | 12 | The module is enabled if `true`, if `false` then the module is disabled. 13 | 14 | ### `url` 15 | 16 | The url of your website 17 | 18 | ### `title` 19 | 20 | The title of your website 21 | 22 | ### `author` 23 | 24 | The author of your website 25 | 26 | ### `site_name` 27 | 28 | The name of your website 29 | 30 | ### `description` 31 | 32 | The description of your website 33 | 34 | ### `theme_color` 35 | 36 | Set a theme color for your website 37 | 38 | ### `img` 39 | 40 | Link to an image for your website preview 41 | 42 | ### `locale` 43 | 44 | The locale of your website 45 | 46 | ### `twitter` 47 | 48 | The module generates twitter meta tags if `true` 49 | 50 | ### `opengraph` 51 | 52 | The module generates opengraph meta tags for facebook, linkedin etc. if `true` 53 | 54 | ### `twitter_user` 55 | 56 | A twitter username for the twitter meta tags 57 | 58 | ### `twitter_card` 59 | 60 | Twitter card property 61 | https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started#started 62 | 63 | ### Example configuration 64 | 65 | ```ts 66 | import { defineNuxtConfig } from "nuxt3"; 67 | 68 | export default defineNuxtConfig({ 69 | modules: ["nuxt-social-tags"], 70 | socialtags: { 71 | enabled: true, 72 | title: "My Title", 73 | theme_color: "#2222", 74 | opengraph: true, 75 | twitter: true, 76 | twitter_user: "heyconnery", 77 | }, 78 | }); 79 | ``` 80 | -------------------------------------------------------------------------------- /docs/content/en/setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Setup" 3 | description: "" 4 | position: 2 5 | category: "Getting started" 6 | --- 7 | 8 | ## Install 9 | 10 | Add `nuxt-social-tags` dependency to your project: 11 | 12 | 13 | 14 | 15 | ```bash 16 | yarn add nuxt-social-tags 17 | ``` 18 | 19 | 20 | 21 | 22 | ```bash 23 | npm install nuxt-social-tags 24 | ``` 25 | 26 | 27 | 28 | 29 | Then add it to the `modules` section in your `nuxt.config.js`: 30 | 31 | ```js{}[nuxt.config.js] 32 | export default { 33 | modules: ["nuxt-social-tags"], 34 | socialtags: {} 35 | }; 36 | ``` 37 | 38 | 39 | 40 | That's it! You can now [configure](/options) the socical meta tags of your Nuxt app ✨ 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/content/en/usage/useSocialTags.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "useSocialTags" 3 | description: "Easily meta-tag generation for Nuxt 3" 4 | position: 8 5 | category: "Usage" 6 | --- 7 | 8 | ### `updateSocialTags` 9 | 10 | Merges the provided module [`options`](/options) with the given data, generates the meta tags and updates them on the page. 11 | 12 | - **Arguments:** 13 | 14 | - data: [`options`](/options) 15 | 16 | ```ts 17 | 22 | ``` 23 | 24 | 25 | 26 | `updateSocialTags` only works during `setup` or [Lifecycle Hooks](https://vuejs.org/api/composition-api-lifecycle.html#composition-api-lifecycle-hooks). 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/content/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Nuxt Social Tags", 3 | "url": "https://nuxt-social-tags.netlify.app/", 4 | "logo": { 5 | "light": "/logo-light.svg", 6 | "dark": "/logo-dark.svg" 7 | }, 8 | "github": "intevel/nuxt-social-tags", 9 | "twitter": "@heyconnery" 10 | } 11 | -------------------------------------------------------------------------------- /docs/nuxt.config.js: -------------------------------------------------------------------------------- 1 | import theme from "@nuxt/content-theme-docs"; 2 | 3 | export default theme({ 4 | docs: { 5 | primaryColor: "#CC3644", 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "nuxt", 7 | "build": "nuxt build", 8 | "start": "nuxt start", 9 | "generate": "nuxt generate" 10 | }, 11 | "dependencies": { 12 | "@nuxt/content-theme-docs": "^0.11.1", 13 | "nuxt": "^2.15.8" 14 | }, 15 | "devDependencies": { 16 | "vue-plausible": "^1.3.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intevel/nuxt-social-tags/161e64b99bfbead64383cd43695757af76b36de1/docs/static/favicon.ico -------------------------------------------------------------------------------- /docs/static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Intevel/nuxt-social-tags/161e64b99bfbead64383cd43695757af76b36de1/docs/static/icon.png -------------------------------------------------------------------------------- /docs/static/logo-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/static/logo-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/static/sw.js: -------------------------------------------------------------------------------- 1 | // THIS FILE SHOULD NOT BE VERSION CONTROLLED 2 | 3 | // https://github.com/NekR/self-destroying-sw 4 | 5 | self.addEventListener('install', function (e) { 6 | self.skipWaiting() 7 | }) 8 | 9 | self.addEventListener('activate', function (e) { 10 | self.registration.unregister() 11 | .then(function () { 12 | return self.clients.matchAll() 13 | }) 14 | .then(function (clients) { 15 | clients.forEach(client => client.navigate(client.url)) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | future: { 3 | removeDeprecatedGapUtilities: true, 4 | purgeLayersByDefault: true, 5 | defaultLineHeights: true, 6 | standardFontWeights: true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-social-tags", 3 | "version": "1.2.3", 4 | "license": "MIT", 5 | "repository": "https://github.com/intevel/nuxt-social-tags", 6 | "homepage": "https://nuxt-social-tags.netlify.app/", 7 | "type": "module", 8 | "author": { 9 | "name": "Conner Luka Bachmann", 10 | "email": "github@conner-bachmann.de" 11 | }, 12 | "contributors": [ 13 | "Intevel " 14 | ], 15 | "exports": { 16 | ".": { 17 | "import": "./dist/module.mjs", 18 | "require": "./dist/module.cjs" 19 | } 20 | }, 21 | "main": "./dist/module.cjs", 22 | "types": "./dist/types.d.ts", 23 | "files": [ 24 | "dist" 25 | ], 26 | "scripts": { 27 | "prepack": "nuxt-module-build", 28 | "dev": "nuxi dev playground", 29 | "dev:build": "nuxi build playground", 30 | "dev:prepare": "nuxt-module-build --stub && nuxi prepare playground", 31 | "release": "nuxt-module-build && standard-version && git push --follow-tags && npm publish", 32 | "lint": "eslint --ext .js,.ts,.vue", 33 | "docs": "cd docs && yarn dev" 34 | }, 35 | "dependencies": { 36 | "@nuxt/kit": "^3.0.0-rc.1" 37 | }, 38 | "devDependencies": { 39 | "@nuxt/module-builder": "latest", 40 | "@nuxtjs/eslint-config-typescript": "latest", 41 | "case-police": "^0.5.3", 42 | "eslint": "latest", 43 | "nuxt": "^3.0.0-rc.1", 44 | "standard-version": "^9.3.2" 45 | }, 46 | "keywords": [ 47 | "nuxt", 48 | "vue.meta", 49 | "nuxtjs", 50 | "nuxt-module", 51 | "vue3", 52 | "nuxt3", 53 | "seo", 54 | "nuxt-social-tags", 55 | "twitter", 56 | "opengraph", 57 | "meta-tags", 58 | "meta", 59 | "nuxt-community" 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /playground/app.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /playground/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtConfig } from "nuxt"; 2 | import MetaTagsModule from ".."; 3 | 4 | export default defineNuxtConfig({ 5 | modules: [MetaTagsModule], 6 | socialtags: { 7 | enabled: true, 8 | title: "My Title", 9 | theme_color: "#2222", 10 | opengraph: true, 11 | twitter: true, 12 | twitter_user: "heyconnery", 13 | }, 14 | }); 15 | -------------------------------------------------------------------------------- /playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "my-module-playground" 4 | } 5 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@nuxtjs"] 3 | } 4 | -------------------------------------------------------------------------------- /src/module.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { defineNuxtModule, addPlugin, addTemplate } from "@nuxt/kit"; 4 | 5 | export interface ModuleOptions { 6 | enabled?: boolean; 7 | url?: string; 8 | title?: string; 9 | author?: string; 10 | site_name?: string; 11 | description?: string; 12 | theme_color?: string; 13 | img?: string; 14 | locale?: string; 15 | twitter?: boolean; 16 | opengraph?: boolean; 17 | twitter_user?: string; 18 | twitter_card?: string; 19 | } 20 | 21 | export default defineNuxtModule({ 22 | meta: { 23 | name: "nuxt-social-tags", 24 | configKey: "socialtags", 25 | compatibility: { 26 | nuxt: "^3.0.0-rc.9", 27 | }, 28 | defaults: { 29 | enabled: true, 30 | }, 31 | }, 32 | 33 | setup(options, nuxt) { 34 | if (options.enabled) { 35 | var metaTags = []; 36 | 37 | metaTags.push( 38 | { name: "title", content: options.title }, 39 | { name: "author", content: options.author }, 40 | { name: "publisher", content: options.author }, 41 | { name: "apple-mobile-web-app-title", content: options.title }, 42 | { name: "theme-color", content: options.theme_color } 43 | ); 44 | 45 | if (options.opengraph) { 46 | metaTags.push( 47 | { property: "og:title", content: options.title }, 48 | { property: "og:description", content: options.description }, 49 | { property: "og:type", content: "website" }, 50 | { property: "og:locale", content: options.locale }, 51 | { property: "og:url", content: options.url }, 52 | { property: "og:image", content: options.img }, 53 | { property: "og:site_name", content: options.site_name } 54 | ); 55 | } 56 | 57 | if (options.twitter) { 58 | metaTags.push( 59 | { name: "twitter:site", content: options.twitter_user }, 60 | { name: "twitter:creator", content: options.twitter_user }, 61 | { name: "twitter:title", content: options.title }, 62 | { name: "twitter:description", content: options.description }, 63 | { name: "twitter:image", content: options.img }, 64 | { name: "twitter:card", content: options.twitter_card } 65 | ); 66 | } 67 | 68 | metaTags = metaTags.filter((x) => x.content); 69 | nuxt.options.app.head.meta = metaTags; 70 | 71 | // Inject options via virtual template 72 | nuxt.options.alias["#social-meta-options"] = addTemplate({ 73 | filename: "social-meta-options.mjs", 74 | getContents: () => 75 | Object.entries(options) 76 | .map( 77 | ([key, value]) => 78 | `export const ${key} = ${JSON.stringify(value, null, 2)}` 79 | ) 80 | .join("\n"), 81 | }).dst; 82 | 83 | const runtimeDir = fileURLToPath(new URL("./runtime", import.meta.url)); 84 | nuxt.options.build.transpile.push(runtimeDir); 85 | 86 | addPlugin(resolve(runtimeDir, "plugin")); 87 | 88 | nuxt.hook("autoImports:dirs", (dirs) => { 89 | dirs.push(resolve(runtimeDir, "composables")); 90 | }); 91 | } 92 | }, 93 | }); 94 | -------------------------------------------------------------------------------- /src/runtime/composables/useSocialTags.ts: -------------------------------------------------------------------------------- 1 | import * as options from "#social-meta-options"; 2 | import { useHead } from "#imports"; 3 | 4 | export const useSocialTags = () => { 5 | const updateSocialTags = async (data: {}): Promise => { 6 | const metaOptions = mergeDeep({ ...options }, { ...data }); 7 | console.log(metaOptions) 8 | var metaTags = []; 9 | 10 | metaTags.push( 11 | { name: "title", content: metaOptions.title }, 12 | { name: "author", content: metaOptions.author }, 13 | { name: "publisher", content: metaOptions.author }, 14 | { name: "apple-mobile-web-app-title", content: metaOptions.title }, 15 | { name: "theme-color", content: metaOptions.theme_color } 16 | ); 17 | 18 | if (metaOptions.opengraph) { 19 | metaTags.push( 20 | { property: "og:title", content: metaOptions.title }, 21 | { property: "og:description", content: metaOptions.description }, 22 | { property: "og:type", content: "website" }, 23 | { property: "og:locale", content: metaOptions.locale }, 24 | { property: "og:url", content: metaOptions.url }, 25 | { property: "og:image", content: metaOptions.img }, 26 | { property: "og:site_name", content: metaOptions.site_name } 27 | ); 28 | } 29 | 30 | if (metaOptions.twitter) { 31 | metaTags.push( 32 | { name: "twitter:site", content: metaOptions.twitter_user }, 33 | { name: "twitter:creator", content: metaOptions.twitter_user }, 34 | { name: "twitter:title", content: metaOptions.title }, 35 | { name: "twitter:description", content: metaOptions.description }, 36 | { name: "twitter:image", content: metaOptions.img }, 37 | { name: "twitter:card", content: metaOptions.twitter_card } 38 | ); 39 | } 40 | 41 | 42 | metaTags = metaTags.filter((x) => x.content); 43 | useHead({ meta: metaTags }); 44 | console.log("[nuxt-social-tags] Updated social meta tags."); 45 | }; 46 | 47 | const isObject = (item) => { 48 | return item && typeof item === "object" && !Array.isArray(item); 49 | }; 50 | 51 | const mergeDeep = (target, ...sources) => { 52 | if (!sources.length) return target; 53 | const source = sources.shift(); 54 | 55 | if (isObject(target) && isObject(source)) { 56 | for (const key in source) { 57 | if (isObject(source[key])) { 58 | if (!target[key]) 59 | Object.assign(target, { 60 | [key]: {}, 61 | }); 62 | mergeDeep(target[key], source[key]); 63 | } else { 64 | Object.assign(target, { 65 | [key]: source[key], 66 | }); 67 | } 68 | } 69 | } 70 | 71 | return mergeDeep(target, ...sources); 72 | }; 73 | 74 | return { updateSocialTags }; 75 | }; 76 | -------------------------------------------------------------------------------- /src/runtime/plugin.ts: -------------------------------------------------------------------------------- 1 | import { defineNuxtPlugin } from "#app"; 2 | import * as options from "#social-meta-options"; 3 | 4 | export default defineNuxtPlugin(async (nuxtApp) => {}); 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./playground/.nuxt/tsconfig.json" 3 | } 4 | --------------------------------------------------------------------------------